#!/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 patacrep.build import SongbookBuilder, DEFAULT_STEPS
from patacrep import __STR_VERSION__
from patacrep 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='+', type=str, action='append',
            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]

    try:
        with open(songbook_path) as songbook_file:
            songbook = json.load(songbook_file)
    except Exception as error: # pylint: disable=broad-except
        LOGGER.error(error)
        LOGGER.error("Error while loading file '{}'.".format(songbook_path))
        sys.exit(1)

    # Gathering datadirs
    datadirs = []
    if options.datadir:
        # Command line options
        datadirs += [item[0] for item in options.datadir]
    if 'datadir' in songbook:
        # .sg file
        if isinstance(songbook['datadir'], basestring):
            songbook['datadir'] = [songbook['datadir']]
        datadirs += [
                os.path.join(
                    os.path.dirname(os.path.abspath(songbook_path)),
                    path
                    )
                for path in songbook['datadir']
                ]
    if not datadirs:
        # Default value
        datadirs = [os.path.dirname(os.path.abspath(songbook_path))]
    songbook['datadir'] = datadirs

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

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

    sys.exit(0)

if __name__ == '__main__':
    main()