import click
import configparser
import time

from creator.content import load_from_json, render
from creator.github import GitHubCreator, GitHubError, DummyGitHub


def prepare_file(cfg, question, filename, message, owner, reponame):
    contents = render(filename, question, owner, reponame)
    return GitHubCreator.filedata(
        contents,
        message,
        cfg['github']['name'],
        cfg['github']['email']
    )


def update_file(cfg, github, question, filename, message, owner, reponame):
    data = prepare_file(cfg, question, filename, message, owner, reponame)
    r = github.get_file(owner, reponame, filename)
    data['sha'] = r.json()['sha']
    return github.upload_file(owner, reponame, filename, data)


def create_file(cfg, github, question, filename, message, owner, reponame):
    data = prepare_file(cfg, question, filename, message, owner, reponame)
    return github.upload_file(owner, reponame, filename, data)


def update_repo(cfg, github, question):
    reponame = cfg['dsq']['repo_prefix'] + question.shortuid
    owner = cfg['github']['owner']

    try:
        update_file(cfg, github, question, 'README.md',
                    'Updated from template (new links)', owner, reponame)
        update_file(cfg, github, question, 'resources/index.md',
                    'Updated from template (new links)', owner, reponame)
    # TODO: customizable messages
    except GitHubError as e:
        click.echo(e, err=True)
        return False

    return True

def create_repo(cfg, github, question):
    # TODO: branch different than master
    reponame = cfg['dsq']['repo_prefix'] + question.shortuid
    owner = cfg['github']['owner']
    repodata = github.repodata(
        reponame,
        cfg['dsq']['description'].format(shortuid=question.shortuid, title=question.title),
        cfg['dsq']['homepage'],
        cfg['dsq']['license_template']
    )

    try:
        github.create_repository(owner, repodata)
        # Give GitHub API some time so no 404 will be returned for upload
        time.sleep(0.5)

        # TODO: make this configurable (YAML?)
        create_file(cfg, github, question, 'README.md',
                    'Autogenerated README file', owner, reponame)
        create_file(cfg, github, question, 'resources/index.md',
                    'Autogenerated resources index', owner, reponame)
    except GitHubError as e:
        click.echo(e, err=True)
        return False

    return True


@click.command()
@click.argument('json_file', type=click.File('r'))
@click.option('-c', '--cfg-file', type=click.File('r'), default='./config.cfg')
@click.option('-u', '--update-only', is_flag=True)
@click.option('-d', '--dry_run', is_flag=True)
def cli(cfg_file, json_file, update_only, dry_run):
    cfg = configparser.ConfigParser()
    cfg.read_file(cfg_file)

    github = DummyGitHub if dry_run else GitHubCreator(cfg['github']['token'])

    total = 0
    ok = 0
    func = update_repo if update_only else create_repo
    for q in load_from_json(json_file):
        click.echo('Creating repository for question ', nl=False)
        click.secho(q.shortuid, bold=True, nl=False)
        click.echo(': ', nl=False)
        if func(cfg, github, q):
            click.secho('OK', bold=True, fg='green')
            ok += 1
        else:
            click.secho('Failed', bold=True, fg='red')
        total += 1
    click.echo('-'*40)
    click.echo('Summary: created {}/{} repositories'.format(ok, total))
