#!/usr/bin/python
# -*- coding: utf-8 -*-
#

"""Command line tool to compile songbooks using the songbook library."""

import argparse
import json
import locale
import logging
import os.path
import textwrap
import sys

from songbook_core.build import SongbookBuilder, DEFAULT_STEPS
from songbook_core import __STR_VERSION__
from songbook_core import errors

# Logging configuration
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger()

# pylint: disable=too-few-public-methods
class ParseStepsAction(argparse.Action):
    """Argparse action to split a string into a list."""
    def __call__(self, __parser, namespace, values, __option_string=None):
        if not getattr(namespace, self.dest):
            setattr(namespace, self.dest, [])
        setattr(
                namespace,
                self.dest,
                (
                    getattr(namespace, self.dest)
                    + [value.strip() for value in values[0].split(',')]
                ),
                )

class VerboseAction(argparse.Action):
    """Set verbosity level with option --verbose."""
    def __call__(self, *_args, **_kwargs):
        LOGGER.setLevel(logging.DEBUG)

def argument_parser(args):
    """Parse argumnts"""
    parser = argparse.ArgumentParser(description="A song book compiler")

    parser.add_argument('--version', help='Show version', action='version',
            version='%(prog)s ' + __STR_VERSION__)

    parser.add_argument('book', nargs=1, help=textwrap.dedent("""\
                    Book to compile.
            """))

    parser.add_argument('--datadir', '-d', nargs=1, type=str, action='store',
            help=textwrap.dedent("""\
                    Data location. Expected (not necessarily required)
                    subdirectories are 'songs', 'img', 'latex', 'templates'.
            """))

    parser.add_argument('--verbose', '-v', nargs=0, action=VerboseAction,
            help=textwrap.dedent("""\
                    Show details about the compilation process.
            """))

    parser.add_argument('--steps', '-s', nargs=1, type=str,
            action=ParseStepsAction,
            help=textwrap.dedent("""\
                    Steps to run. Default is "{steps}".
                    Available steps are:
                    "tex" produce .tex file from templates;
                    "pdf" compile .tex file;
                    "sbx" compile index files;
                    "clean" remove temporary files;
                    any string beginning with '%%' (in this case, it will be run
                    in a shell). Several steps (excepted the custom shell
                    command) can be combinend in one --steps argument, as a
                    comma separated string.
            """.format(steps=','.join(DEFAULT_STEPS))),
            default=None,
            )

    options = parser.parse_args(args)

    return options


def main():
    """Main function:"""

    # set script locale to match user's
    try:
        locale.setlocale(locale.LC_ALL, '')
    except locale.Error as error:
        # Locale is not installed on user's system, or wrongly configured.
        sys.stderr.write("Locale error: {}\n".format(error.message))

    options = argument_parser(sys.argv[1:])

    songbook_path = options.book[0]

    basename = os.path.basename(songbook_path)[:-3]

    with open(songbook_path) as songbook_file:
        songbook = json.load(songbook_file)

    if options.datadir is not None:
        songbook['datadir'] = options.datadir[0]
    elif 'datadir' in songbook.keys():
        if not os.path.isabs(songbook['datadir']):
            songbook['datadir'] = os.path.join(os.path.dirname(songbook_path),
                                               songbook['datadir']
                                               )
    else:
        songbook['datadir'] = os.path.dirname(songbook_path)

    try:
        sb_builder = SongbookBuilder(songbook, basename)
        sb_builder.unsafe = True

        sb_builder.build_steps(options.steps)
    except errors.SongbookError as error:
        LOGGER.error(error)
        LOGGER.error(
                "Running again with option '-v' may give more information."
                )
        sys.exit(1)

    sys.exit(0)

if __name__ == '__main__':
    main()