#!/usr/bin/env python3
from argparse import ArgumentParser
from sys import argv

from vang.bitbucket.create_repo import create_repo
from vang.bitbucket.enable_webhooks import enable_repo_web_hook
from vang.bitbucket.get_clone_urls import get_clone_urls
from vang.bitbucket.set_default_branches import set_repo_default_branch
from vang.misc.s import get_zipped_cases
from vang.pio.rsr import get_replace_function, rsr
from vang.pio.shell import run_command


def setup(project, repo, src_branch, dest_project, dest_repo, dest_branch, work_dir):
    clone_url = [c for _, p, r, c in get_clone_urls([project]) if r == repo][0]
    dest_repo_dir = f'{work_dir}/{dest_project}/{dest_repo}'
    run_command(f'git clone -b {src_branch} {clone_url} {dest_repo_dir}')
    run_command('rm -rf .git', return_output=True, cwd=dest_repo_dir)
    run_command('git init', return_output=True, cwd=dest_repo_dir)
    if not dest_branch == 'master':
        run_command(f'git checkout -b {dest_branch}', return_output=True, cwd=dest_repo_dir)
    return clone_url, dest_repo_dir


def commit_all(repo_dir):
    run_command('git add --all', return_output=True, cwd=repo_dir)
    run_command(
        'git commit -m "Initial commit"',
        return_output=True,
        cwd=repo_dir,
    )


def update(repo, dest_repo, dest_repo_dir):
    for old, new in get_zipped_cases([repo, dest_repo]):
        rsr(old, new, [dest_repo_dir], get_replace_function(False))


def create_and_push_to_dest_repo(dest_project,
                                 dest_repo,
                                 dest_branch,
                                 dest_repo_dir,
                                 webhook=None):
    dest_repo_origin = create_repo(dest_project, dest_repo)['links']['clone'][0]['href']
    if webhook:
        enable_repo_web_hook([dest_project, dest_repo], webhook)
    run_command(f'git remote add origin {dest_repo_origin}',
                return_output=True,
                cwd=dest_repo_dir)
    run_command(f'git push -u origin {dest_branch}', return_output=True, cwd=dest_repo_dir)
    set_repo_default_branch((dest_project, dest_repo), dest_branch)
    return dest_repo_origin


def parse_args(args):
    parser = ArgumentParser(
        description='Create a new repo based on template repo.\nExample: '
                    'create_from_template PCS1806 foo PCS1806 bar -sb '
                    'develop -db 1.0.x -d . -w http://my-host:7777/wildcat/webhook/')
    parser.add_argument(
        'src_project',
        help='The project from which to create the new repo (must exist)')
    parser.add_argument(
        'src_repo',
        help='The repo from which to create the new repo (must exist)')
    parser.add_argument(
        'dest_project',
        help='The project in which to create the new repo (must exist)')
    parser.add_argument(
        'dest_repo',
        help='The new repo (must not exist)')
    parser.add_argument(
        '-sb',
        '--src_branch',
        default='develop',
        help='The branch to use, e.g. develop')
    parser.add_argument(
        '-db',
        '--dest_branch',
        help='The branch to create, e.g. develop. '
             'Will be set to src_branch if not specified. '
             'It will be set as default branch on created repo')
    parser.add_argument(
        '-d',
        '--work_dir',
        default='.',
        help='The directory to create local repo in (directory work_dir/src_project/src_repo must not exists)')
    parser.add_argument(
        '-w',
        '--webhook',
        default=False,
        help='Webhook url to add to the new repo')
    return parser.parse_args(args)


def main(src_project, src_repo, src_branch, dest_project, dest_repo, dest_branch, work_dir, webhook):
    if not dest_branch:
        dest_branch = src_branch
    clone_url, dest_repo_dir = setup(src_project, src_repo, src_branch, dest_project, dest_repo, dest_branch, work_dir)
    update(src_repo, dest_repo, dest_repo_dir)
    commit_all(dest_repo_dir)
    dest_repo_origin = create_and_push_to_dest_repo(dest_project, dest_repo, dest_branch, dest_repo_dir, webhook)
    print('Created', dest_repo_origin)


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