# -*- coding: utf-8 -*-
"""Command-line interface to Kajiki to render a single template."""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import argparse
import os
import site
import sys

import kajiki.loader


def _kv_pair(pair):
    """Convert a KEY=VALUE string to a 2-tuple of (KEY, VALUE).

    This is intended for usage with the type= argument to argparse.
    """
    key, sep, value = pair.partition('=')
    if not sep:
        raise argparse.ArgumentTypeError(
            'Expected a KEY=VALUE pair, got {}'.format(pair))
    return key, value


def main(argv=None):
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-m', '--mode',
        dest='force_mode',
        choices=['text', 'xml', 'html', 'html5'],
        help=('Force a specific templating mode instead of auto-detecting '
              'based on extension.'),
    )
    parser.add_argument(
        '-i', '--path',
        action='append',
        dest='paths',
        default=[],
        metavar='path',
        help=("Add to the file loader's include paths.  For the package "
              "loader, this will add the path to Python's site directories."),
    )
    parser.add_argument(
        '-v', '--var',
        action='append',
        dest='template_variables',
        default=[],
        type=_kv_pair,
        metavar='KEY=VALUE',
        help='Template variables, passed as KEY=VALUE pairs.',
    )
    parser.add_argument(
        '-p', '--package',
        dest='loader_type',
        action='store_const',
        const=kajiki.loader.PackageLoader,
        default=kajiki.loader.FileLoader,
        help='Load based on package name instead of file path.',
    )
    parser.add_argument(
        'file_or_package',
        help='Filename or package to load.',
    )
    parser.add_argument(
        'output_file',
        type=argparse.FileType('w'),
        default=sys.stdout,
        nargs='?',
        help='Output file.  If unspecified, use stdout.',
    )

    opts = parser.parse_args(argv)

    loader_kwargs = {}
    if opts.loader_type is kajiki.loader.PackageLoader:
        for path in opts.paths:
            site.addsitedir(path)
    else:
        opts.paths.append(os.path.dirname(opts.file_or_package) or '.')
        loader_kwargs['path'] = opts.paths

    loader = opts.loader_type(
        force_mode=opts.force_mode,
        **loader_kwargs)
    template = loader.import_(opts.file_or_package)
    result = template(dict(opts.template_variables)).render()
    opts.output_file.write(result)

    # Close the output file to avoid a ResourceWarning during unit
    # tests on Python 3.4+.  But don't close stdout, just flush it
    # instead.
    if opts.output_file is sys.stdout:
        opts.output_file.flush()
    else:
        opts.output_file.close()


if __name__ == '__main__':
    main(sys.argv[1:])  # pragma: no cover
