#!/usr/bin/env python
"""
This script parses the SALAMI v2.0 dataset into the JAMS format.

Usage example:
    ./salami_parser.py salami-data-public/ OutputSalamiJAMS
"""

import argparse
import csv
from joblib import Parallel, delayed
import logging
import numpy as np
import os
import pandas as pd
import re
import time

import jams

__author__ = "Oriol Nieto"
__copyright__ = "Copyright 2016, Music and Audio Research Lab (MARL)"
__license__ = "MIT"
__version__ = "1.2"
__email__ = "oriol@nyu.edu"

SALAMI_VERSION = "2.0"
SALAMI_CORPUS_NAME = "SALAMI"
SALAMI_ANN_TOOL = "Sonic Visualiser"
SALAMI_CURATOR = "Jordan Smith"
SALAMI_EMAIL = "jblsmith@gmail.com"

# Mapping of the labels to the actual labels allowed by the SALAMI guidelines
labels_map = {
    "a'/a''": "no_function",
    "b/c'": "no_function",
    "bagpipes": "instrumental",
    "banjo": "instrumental",
    "code": "coda",
    "dialog": "spoken",
    "female": "voice_female",
    "first": "main theme",
    "guitar": "instrumental",
    "hammond": "instrumental",
    "main_theme": "main theme",
    "male": "voice_male",
    "muted": "fade-out",
    "organ": "instrumental",
    "out": "outro",
    "piano": "instrumental",
    "recap": "recapitulation",
    "secondary_theme": "secondary theme",
    "spoken_voice": "spoken",
    "stage_speaking": "spoken",
    "steel": "instrumental",
    "tag": "head",
    "trumpet": "instrumental",
    "third": "third theme",
    "violin": "instrumental",
    "vocalizations": "voice",
    "vocals": "voice",
    "w/dialog": "spoken"
}


def fix_label(label):
    """Fixes the given label to comply the SALAMI guidelines and JAMS
    namespace."""
    label = label.lower()
    return labels_map.get(label, label)


def fill_global_metadata(jam, metadata, dur):
    """Fills the global metada into the JAMS jam."""
    meta = jams.FileMetadata(title=metadata[7],
                             artist=metadata[8],
                             duration=dur,
                             jams_version=jams.version.version)
    jam.file_metadata = meta


def get_level_segments(df, level):
    """Gets the segments for the given level.

    Parameters
    ----------
    df: pandas.DataFrame
        DataFrame containing all the boundaries from the raw file.