#!/usr/bin/env python
import argparse
import logging
import sys
import yaml

import docker_buildtool
from docker_buildtool import git_version

logger = logging.getLogger()
formatter = logging.Formatter('[%(asctime)s] %(message)s')
handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(formatter)
logger.addHandler(handler)

def build(args):
    variables = {}
    for k_v in args.variable:
        k, v = k_v.split('=', 2)
        variables[k] = v

    if args.docker_args and args.docker_args[0] == '--':
        args.docker_args = args.docker_args[1:]
    builder = docker_buildtool.Builder(
        args.dockerfile,
        image=args.tag,
        variables=variables,
        fetch=args.fetch,
        force_rsync=args.rsync,
        docker_args=args.docker_args,
        safe_dockerignore=args.safe_dockerignore,
    )
    builder.run(dryrun=args.dryrun)

def pull(args):
    puller = docker_buildtool.Puller(dockerfile=args.dockerfile)
    puller.run(dryrun=args.dryrun)

def version(args):
    versioner = docker_buildtool.Versioner(dockerfile=args.dockerfile)
    logger.info('Note: the following fetch commands may take a while to run.')
    versions = versioner.run(fetch=args.fetch)

    if args.yaml:
        full_version_string = yaml.dump(versions)
    else:
        full_version_string = '\n\n'.join([
'''{bar}\n{name}\n{bar}
{version_string}'''.format(name=name, bar="="*max(len(name), 50), version_string=git_version.pretty_string(version))
            for (name, version) in sorted(versions.items())])

    logger.critical('\n' + full_version_string)
    if args.outfile is not None:
        with open(args.outfile, 'w') as f:
            logger.info('Writing version string to %s', args.outfile)
            f.write(full_version_string)

def main():
    parser = argparse.ArgumentParser(description=None)
    parser.add_argument('-v', '--verbose', action='count', dest='verbosity', default=0, help='Set verbosity.')
    parser.add_argument('-f', '--dockerfile', default='Dockerfile', help='Which Dockerfile to use.')

    subparsers = parser.add_subparsers()
    sub = subparsers.add_parser('build')
    sub.add_argument('--fetch', action='store_true', help='Fetch git repos')
    sub.add_argument('--rsync', default=None, action='store_true', help='Use rsync instead of tar')
    sub.add_argument('-t', '--tag', help='The tag to use.')
    sub.add_argument('-v', '--variable', default=[], nargs='+', help='Value of docker-buildtool varable of the form KEY=VALUE.')
    sub.add_argument('-n', '--dryrun', action='store_true', help='Do not actually run')
    sub.add_argument('--safe-dockerignore', action='store_true', help='Use a build-specific .dockerignore file. Only works on Docker 19.03 and later. This flag is necessary if you want to safely build multiple docker images from the same build root at the same time.')
    sub.add_argument('docker_args', nargs=argparse.REMAINDER, help='Arguments to pass to docker build')
    sub.set_defaults(func=build)

    sub = subparsers.add_parser('pull')
    sub.add_argument('-n', '--dryrun', action='store_true', help='Do not actually run')
    sub.set_defaults(func=pull)

    sub = subparsers.add_parser('version')
    sub.add_argument('--fetch', action='store_true', help='Fetch git repos')
    sub.add_argument('-o', '--outfile', default=None, help='Optional output file to save the version string')
    sub.add_argument('-y', '--yaml', action='store_true', default=False, help='Print as YAML')
    sub.set_defaults(func=version)

    args = parser.parse_args()

    if args.verbosity == 0:
        logger.setLevel(logging.INFO)
    elif args.verbosity >= 1:
        logger.setLevel(logging.DEBUG)

    if hasattr(args, 'func'):
        args.func(args)
    else:
        parser.print_help()

    return 0

if __name__ == '__main__':
    sys.exit(main())
