from musiclang_predict import MusicLangTokenizer
from musiclang.library import *


default_options = {
    'chord_change_token': True,
    'melody_end_token': True,
    'chord_duration_token': True,
    'density_token': True,
    'chord_extension_token': True,
    'next_chord_token': True,
    'next_chord_duration_token': True,
    'will_end_token': True,
    'dissonance_token': True,
    'amplitude_token': True,
    'average_octave_token': True,
    'voice_token': True,
    'random_instrument_permutation': False
}

def test_tokenizer():


    tokenizer = MusicLangTokenizer(options=default_options)
    score = (I % I.M).o(-1)(
        piano__0=s0.o(1).e + s1.e + s2,
        violin__1=s3.o(1).e + h3.e.p + s5,
        piano__5=s6.o(1).e + s3.e + s2,
    ) * 2

    tokens = tokenizer.tokenize(score)
    score_parsed = tokenizer.untokenize(tokens)

    assert score == score_parsed



def test_cut_bar():
    text = """
    CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__3 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 WILL_END INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END END
    """
    tokenizer = MusicLangTokenizer()

    score = tokenizer.untokenize(text)
    assert all([mel.duration == 3 for key, mel in score[0].score.items()])

def test_add_bar():
    text = """
    CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__5 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 NEXT_CHORD_DEGREE__0 NEXT_TONALITY_DEGREE__0 NEXT_TONALITY_MODE__M NEXT_CHORD_OCTAVE__0 NEXT_CHORD_DURATION_NUM__4 NEXT_CHORD_DURATION_DEN__1 INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END CHORD_CHANGE CHORD_DEGREE__0 TONALITY_DEGREE__0 TONALITY_MODE__M CHORD_OCTAVE__0 CHORD_EXTENSION__65 CHORD_DURATION_NUM__4 CHORD_DURATION_DEN__1 WILL_END INSTRUMENT_NAME__violin INSTRUMENT_PART__1 DENSITY__medium AVERAGE_OCTAVE__0 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__4 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 NOTE_TYPE__s NOTE_VAL__2 NOTE_OCTAVE__0 NOTE_AMP__mf NOTE_DURATION_NUM__1 NOTE_DURATION_DEN__1 MELODY_END INSTRUMENT_NAME__piano INSTRUMENT_PART__2 DENSITY__low AVERAGE_OCTAVE__-1 AMPLITUDE__mf NOTE_TYPE__s NOTE_VAL__0 NOTE_OCTAVE__-1 NOTE_AMP__mf NOTE_DURATION_NUM__4 NOTE_DURATION_DEN__1 MELODY_END END
    """
    tokenizer = MusicLangTokenizer()
    score = tokenizer.untokenize(text)
    assert all([mel.duration == 5 for key, mel in score[0].score.items()])