import argparse
import sys

from vcs2l.clients import vcs2l_clients
from vcs2l.commands.command import Command, add_common_arguments
from vcs2l.commands.import_ import get_repositories
from vcs2l.executor import ansi, execute_jobs, output_results
from vcs2l.streams import set_streams


class ValidateCommand(Command):
    command = 'validate'
    help = 'Validate the repository list file'

    def __init__(self, args, url, version=None):
        super(ValidateCommand, self).__init__(args)
        self.url = url
        self.version = version
        self.retry = args.retry


def get_parser():
    parser = argparse.ArgumentParser(
        description='Validate a repositories file', prog='vcs validate'
    )
    group = parser.add_argument_group('"validate" command parameters')
    group.add_argument('--input', type=argparse.FileType('r'), default='-')
    group.add_argument(
        '--retry',
        type=int,
        metavar='N',
        default=2,
        help='Retry commands requiring network access N times on failure',
    )
    return parser


def generate_jobs(repos, args):
    jobs = []
    for path, repo in repos.items():
        clients = [c for c in vcs2l_clients if c.type == repo['type']]
        if not clients:
            from vcs2l.clients.none import NoneClient

            job = {
                'client': NoneClient(path),
                'command': None,
                'cwd': path,
                'output': "Repository type '%s' is not supported" % repo['type'],
                'returncode': NotImplemented,
            }
            jobs.append(job)
            continue

        client = clients[0](path)
        args.path = None  # expected to be present
        command = ValidateCommand(
            args, repo['url'], str(repo['version']) if 'version' in repo else None
        )
        job = {'client': client, 'command': command}
        jobs.append(job)
    return jobs


def main(args=None, stdout=None, stderr=None):
    set_streams(stdout=stdout, stderr=stderr)

    parser = get_parser()
    add_common_arguments(parser, skip_nested=True, path_nargs=False)
    args = parser.parse_args(args)
    try:
        repos = get_repositories(args.input)
    except RuntimeError as e:
        print(ansi('redf') + str(e) + ansi('reset'), file=sys.stderr)
        return 1

    jobs = generate_jobs(repos, args)

    results = execute_jobs(
        jobs, show_progress=True, number_of_workers=args.workers, debug_jobs=args.debug
    )

    output_results(results, hide_empty=args.hide_empty)

    any_error = any(r['returncode'] for r in results)
    return 1 if any_error else 0


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