#! /usr/bin/env python
# encoding: utf-8

import os
import re

from functools import reduce
from waflib import TaskGen

APPNAME = 'kommersbuch'
VERSION = '1.0'

top = '.'
out = 'build'
src = 'src'
lib = 'lib'
src_scores = os.path.join(src, 'scores')
src_lyrics = os.path.join(src, 'lyrics')
built_lyrics_path = os.path.abspath(os.path.join(out, src, 'lyrics'))
built_scores_path = os.path.abspath(os.path.join(out, src, 'scores'))
templater_path = os.path.abspath(os.path.join(src, 'tools/templater.py'))
score_lyrics_template_path = os.path.abspath(
    os.path.join(src, 'templates', 'score_lyrics.j2'))
book_template_path = os.path.abspath(
    os.path.join(src, 'templates', 'book.j2'))


def dist(ctx):
    ctx.excl = '**/.waf* **/*~ **/*.pyc **/*.swp **/.lock* out pdf midi music .git .DS_Store'


def configure(ctx):
    ctx.find_program('lualatex', var='LUALATEX')
    ctx.find_program('lilypond', var='LILYPOND')
    ctx.find_program('timidity', var='TIMIDITY')
    ctx.find_program('opusenc', var='OPUSENC')


def pre(ctx):
    os.system('mkdir -p {1} && cp -r {0}/* {1}'.format(lib, built_lyrics_path))

TaskGen.declare_chain(
    name='opus',
    rule='${TIMIDITY} ${SRC} -Ow -o - | ${OPUSENC} - ${TGT}',
    ext_in='.midi',
    ext_out='.opus',
    shell=True)


def build(ctx):
    ctx.add_pre_fun(pre)

    ctx.add_group('lilypond')
    ctx.add_group('opus')
    ctx.add_group('book')

    lilypond_rule = '${LILYPOND} -o ${TGT[0].abspath().replace(".pdf", "")} ${SRC}'
    lyrics_template_rule = templater_path + ' ' + \
        score_lyrics_template_path + ' "{0}" > ${{TGT}}'
    book_template_rule = templater_path + ' ' + \
        book_template_path + ' "{0}" > ${{TGT}}'
    lyrics_combined_rule = 'cd ' + built_lyrics_path + \
        ' && ${LUALATEX} --shell-escape '

    scoredata = []
    scores = ctx.path.ant_glob(src_scores + '/*.ly')
    for score in scores:
        filename = os.path.basename(score.abspath())

        lyricsfile = os.path.join(src_lyrics, filename.replace('.ly', '.tex'))
        lilyfile = filename.replace('.ly', '.pdf')
        lily_score_file = '{0}_score.pdf'.format(
            lilyfile.replace('.pdf', ''))
        lily_midi_file = lilyfile.replace('.pdf', '_score.midi')
        target_files = '{0} {1} {2}'.format(
            os.path.join(src_scores, lilyfile),
            os.path.join(src_scores, lily_score_file),
            os.path.join(src_scores, lily_midi_file))

        score_content = ''
        with open(score.abspath(), 'r') as f:
            score_content = f.read()

        matches = re.findall('title = "(.*)"', score_content)
        score_title = matches[0]

        scoredata.append(
            {'title': score_title,
             'score': score.abspath(),
             'lyrics': os.path.abspath(lyricsfile)})

        ctx.set_group('lilypond')

        # score without lyrics & midi

        ctx(
            rule=lilypond_rule,
            source=score,
            target=target_files,
            shell=True
        )

        # score with lyrics

        template_data = {
            'score_file': score.abspath(),
            'lyrics_file': os.path.abspath(lyricsfile)
        }

        lyrics_rule = lyrics_template_rule.format(str(template_data))
        built_lyricsfile = os.path.join(
            src_lyrics,
            filename.replace('.ly', '_built.tex'))

        ctx(
            rule=lyrics_rule,
            source=lyricsfile,
            target=built_lyricsfile,
            shell=True
        )

        final_lyrics_path = os.path.join(
            built_scores_path, filename.replace('.ly', '_lyrics.pdf'))

        lyrics_combined_rule_final = lyrics_combined_rule + \
            filename.replace('.ly', '_built.tex') + \
            ' && cp ' + filename.replace('.ly', '_built.pdf') + \
            ' ' + final_lyrics_path

        ctx(
            rule=lyrics_combined_rule_final,
            source=score.relpath() + ' ' + built_lyricsfile,
            target=os.path.join(
                src_scores, filename.replace('.ly', '_lyrics.pdf')),
            shell=True
        )

        # opus

        ctx.set_group('opus')
        ctx(source=os.path.join(src_scores, lily_midi_file))

    # booklet

    template_data = {
        'scores': scoredata,
    }

    book_rule = book_template_rule.format(str(template_data))
    built_bookfile = os.path.join(src_lyrics, 'book.tex')

    ctx.set_group('book')
    ctx(
        rule=book_rule,
        source=os.path.relpath(book_template_path),
        target=built_bookfile,
        shell=True
    )

    final_book_path = os.path.join(built_scores_path, 'book.pdf')
    book_combined_rule_final = lyrics_combined_rule + \
        'book.tex' + \
        ' && cp book.pdf' + \
        ' ' + final_book_path

    book_sources = os.path.relpath(book_template_path)
    for score in scoredata:
        book_sources = '{0} {1} {2}'.format(
            book_sources,
            os.path.relpath(score['score']),
            os.path.relpath(score['lyrics']))

    ctx(
        rule='{0} && {0}'.format(book_combined_rule_final),
        source=book_sources,
        target=os.path.join(src_scores, 'book.pdf'),
        shell=True
    )