#!/usr/bin/env python3
import argparse
import os
from pathlib import Path
import shutil
import subprocess
import sys
from tempfile import TemporaryDirectory
from uuid import uuid4
from zipfile import ZipFile

import jinja2
import sente  # type: ignore

__version__ = (1, 0, 0)

SGF_RENDER_EXECUTABLE = './sgf-render'

TEMPLATEDIR = Path(__file__, '..', 'epub_template').resolve()


def load_sgf(sgfpath: Path):
    game = sente.sgf.load(str(sgfpath))
    comments = {}
    seq = game.get_default_sequence()
    for idx, move in enumerate(seq, 1):
        game.play(move)
        if game.comment:
            comments[idx] = game.comment
    return {
        # read only main sequence, not variations
        'nb_moves': len(seq),
        'metadata': game.get_properties(),
        'comments': comments,
    }


def main(sgfpath: Path, output_path: Path) -> None:
    print()
    print(f'Load content of {sgfpath}')
    try:
        sgf_content = load_sgf(sgfpath)
    except (sente.exceptions.InvalidSGFException,
            sente.exceptions.IllegalMoveException):
        print(f'Could not read {sgfpath}, skipping')
        return
    nb_moves = sgf_content['nb_moves']
    metadata = sgf_content['metadata']
    comments = sgf_content['comments']

    uuid = uuid4()

    with TemporaryDirectory() as tmpdir:
        print('Prepare structure of the ebook')
        shutil.copytree(TEMPLATEDIR, tmpdir, dirs_exist_ok=True)

        template = jinja2.Template(
            TEMPLATEDIR.joinpath('EPUB', 'Text', 'page_001.html').open().read())

        print('Prepare SVG diagrams')
        svgdirpath = Path(tmpdir, 'EPUB', 'Images')
        for move in range(1, nb_moves + 1):
            svgpath = f'diagram_{move:03}.svg'
            # generate SVG files with sgf-render
            try:
                subprocess.check_call([
                    SGF_RENDER_EXECUTABLE,
                    str(sgfpath),
                    '--move-numbers',
                    '--first-move-number', str(move),
                    '-n', str(move),
                    '--style', 'minimalist',
                    '-o', svgdirpath.joinpath(svgpath),
                ])
            except subprocess.CalledProcessError:
                print(f'Move {move} could not be converted to SVG')
                continue

            # replace move number in SVG
            # not possible directly in sgf-render invocation at the moment
            svg_content = svgdirpath.joinpath(svgpath).open().read()
            svgdirpath.joinpath(svgpath).open('w').write(
                svg_content.replace('>1<', f'>{move}<', 1))

            # create HTML page with SVG element
            html_content = template.render(
                title=sgfpath.stem,
                svgpath=svgpath,
                info=metadata,
                first_flag=(move == 1),
                last_flag=(move == nb_moves),
                comment=comments.get(move, ''),
            )
            with Path(tmpdir, 'EPUB', 'Text', f'page_{move:03}.html').open('w') as fd:
                fd.write(html_content)

        # Declare all HTML/SVG files in master file
        print('Prepare content.opf file')
        template = jinja2.Template(
            TEMPLATEDIR.joinpath('EPUB', 'content.opf').open().read())
        opf_content = template.render(
            title=sgfpath.stem,
            creator='sgf2ebook',
            UUID=uuid,
            svgpath=sorted(svgdirpath.glob('*.svg')),
            enumerate=enumerate,
        )
        with Path(tmpdir, 'EPUB', 'content.opf').open('w') as fd:
            fd.write(opf_content)

        # Generate table of contents
        print('Prepare table of contents')
        template = jinja2.Template(
            TEMPLATEDIR.joinpath('EPUB', 'toc.ncx').open().read())
        toc_content = template.render(
            title=sgfpath.stem,
            UUID=uuid,
            nb_moves=nb_moves,
            range=range,
        )
        with Path(tmpdir, 'EPUB', 'toc.ncx').open('w') as fd:
            fd.write(toc_content)

        # zip all content in EPUB file
        output_path.mkdir(exist_ok=True, parents=True)
        output_name = f"{metadata.get('EV', 'unknown_event')}{'_' if 'RO' in metadata else ''}{metadata.get('RO', '')}.epub".replace(' ', '_')
        with ZipFile(output_path.joinpath(output_name), 'w') as zf:
            os.chdir(tmpdir)
            # "The first file in the OCF ZIP Container MUST be the mimetype file"
            zf.write('mimetype')
            for root, dirs, files in os.walk('.'):
                for file in sorted(files):
                    if file != 'mimetype':
                        zf.write(Path(root, file))
            os.chdir(Path(__file__).parent)
    print(f'{output_path.joinpath(output_name)} generated')


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='')
    parser.add_argument('--input-path', '-i', help='Input files or directory')
    parser.add_argument('--output-path', '-o', help='Output directory')
    args = parser.parse_args()

    path = Path(args.input_path)
    outpath = Path(args.output_path)
    if not path.exists():
        print(f'Input path {path} not found')
        sys.exit(1)
    if path.is_file():
        main(path, outpath)
    if path.is_dir():
        for filepath in sorted(path.rglob('*.sgf')):
            main(filepath, outpath.joinpath(filepath.parent.relative_to(path)))

[((51, 11, 51, 18), 'uuid.uuid4', 'uuid4', ({}, {}), '()', False, 'from uuid import uuid4\n'), ((140, 13, 141, 23), 'argparse.ArgumentParser', 'argparse.ArgumentParser', (), '', False, 'import argparse\n'), ((146, 11, 146, 32), 'pathlib.Path', 'Path', ({(146, 16, 146, 31): 'args.input_path'}, {}), '(args.input_path)', False, 'from pathlib import Path\n'), ((147, 14, 147, 36), 'pathlib.Path', 'Path', ({(147, 19, 147, 35): 'args.output_path'}, {}), '(args.output_path)', False, 'from pathlib import Path\n'), ((19, 14, 19, 51), 'pathlib.Path', 'Path', ({(19, 19, 19, 27): '__file__', (19, 29, 19, 33): '""".."""', (19, 35, 19, 50): '"""epub_template"""'}, {}), "(__file__, '..', 'epub_template')", False, 'from pathlib import Path\n'), ((53, 9, 53, 29), 'tempfile.TemporaryDirectory', 'TemporaryDirectory', ({}, {}), '()', False, 'from tempfile import TemporaryDirectory\n'), ((55, 8, 55, 64), 'shutil.copytree', 'shutil.copytree', (), '', False, 'import shutil\n'), ((61, 21, 61, 51), 'pathlib.Path', 'Path', ({(61, 26, 61, 32): 'tmpdir', (61, 34, 61, 40): '"""EPUB"""', (61, 42, 61, 50): '"""Images"""'}, {}), "(tmpdir, 'EPUB', 'Images')", False, 'from pathlib import Path\n'), ((150, 8, 150, 19), 'sys.exit', 'sys.exit', ({(150, 17, 150, 18): '(1)'}, {}), '(1)', False, 'import sys\n'), ((128, 12, 128, 28), 'os.chdir', 'os.chdir', ({(128, 21, 128, 27): 'tmpdir'}, {}), '(tmpdir)', False, 'import os\n'), ((131, 37, 131, 49), 'os.walk', 'os.walk', ({(131, 45, 131, 48): '"""."""'}, {}), "('.')", False, 'import os\n'), ((108, 13, 108, 48), 'pathlib.Path', 'Path', ({(108, 18, 108, 24): 'tmpdir', (108, 26, 108, 32): '"""EPUB"""', (108, 34, 108, 47): '"""content.opf"""'}, {}), "(tmpdir, 'EPUB', 'content.opf')", False, 'from pathlib import Path\n'), ((121, 13, 121, 44), 'pathlib.Path', 'Path', ({(121, 18, 121, 24): 'tmpdir', (121, 26, 121, 32): '"""EPUB"""', (121, 34, 121, 43): '"""toc.ncx"""'}, {}), "(tmpdir, 'EPUB', 'toc.ncx')", False, 'from pathlib import Path\n'), ((135, 21, 135, 35), 'pathlib.Path', 'Path', ({(135, 26, 135, 34): '__file__'}, {}), '(__file__)', False, 'from pathlib import Path\n'), ((94, 17, 94, 69), 'pathlib.Path', 'Path', ({(94, 22, 94, 28): 'tmpdir', (94, 30, 94, 36): '"""EPUB"""', (94, 38, 94, 44): '"""Text"""', (94, 46, 94, 68): 'f"""page_{move:03}.html"""'}, {}), "(tmpdir, 'EPUB', 'Text', f'page_{move:03}.html')", False, 'from pathlib import Path\n'), ((134, 33, 134, 49), 'pathlib.Path', 'Path', ({(134, 38, 134, 42): 'root', (134, 44, 134, 48): 'file'}, {}), '(root, file)', False, 'from pathlib import Path\n')]