#!/usr/bin/env python3

from gitz.git import GIT
from gitz.git import functions
from gitz.git import root
from gitz.program import ARGS
from gitz.program import PROGRAM
from pathlib import Path
import webbrowser

SUMMARY = 'Open a browser page for the current repo'

HELP = """
Usage:

  ``git go [<location>]``

where <location> is one or more letters from:

* between: open *all* commits between HEAD and main or master

* commits: the list of commits for the current branch (the default)

* directory: the subdirectory in the current branch

* issues: the issues page

* new_releases: a form to create new releases

* pull: open the form for a pull request

* releases: a list of existing releases

* source: the root directory for the branch

* travis: the Travis page for that repo
"""

EXAMPLES = """

git go

"""

# https://travis-ci.com/github/rec/gitz

GITHUB = {
    'between': 'https://{host}/{user}/{project}/commits/{branch}',
    'commits': 'https://{host}/{user}/{project}/commits/{branch}',
    'directory': 'https://{host}/{user}/{project}/tree/{branch}/{path}',
    'issues': 'https://{host}/{user}/{project}/issues',
    'new_releases': 'https://{host}/{user}/{project}/releases/new',
    'pulls': (
        'https://{host}/{up}/{project}/compare/main...{user}:{branch}?expand=1'
    ),
    'releases': 'https://{host}/{user}/{project}/releases',
    'source': 'https://{host}/{user}/{project}/tree/{branch}',
    'travis': 'https://travis-ci.com/{host_name}/{user}/{project}',
}

URLS = {'github.com': GITHUB}


def open_url(url, new=0):
    webbrowser.open(url, new=new, autoraise=True)



def git_go():
    host, host_name, user, project = _get_remote('origin')
    urls = URLS[host]
    cmds = {c for c in urls if c.startswith(ARGS.cmd)}
    if not cmds:
        PROGRAM.exit('Do not understand command', ARGS.cmd)
    cmd = cmds.pop()
    if cmds:
        PROGRAM.exit('Ambiguous command', ARGS.cmd)

    url = urls[cmd]
    if '{branch}' in url:
        branch = functions.branch_name()

    if '{path}' in url:
        path = Path().absolute().relative_to(root.root())

    if '{up}' in url:
        upstream = _get_remote('upstream')
        up = upstream and upstream[2] or user

    url = url.format(**locals())
    if cmd == 'between':
        _between(url)
    else:
        print('Opening url', url)
        open_url(url)


def _between(url):
    commit_ids = _commits()
    if not commit_ids:
        PROGRAM.exit('No commit IDs found')

    root, _ = url.rsplit('/', maxsplit=1)
    assert root.endswith('commits')
    root = root[:-1]

    open_url(url, new=1)
    for u in (f'{root}/{c}' for c in reversed(commit_ids)):
        open_url(u)


def _commits():
    for branch in 'main', 'master':
        try:
            r = GIT.rev_list('--ancestry-path', f'{branch}..HEAD')
        except Exception:
            pass
        else:
            if r:
                s = (len(r) != 1) * 's'
                print(f'Opening {len(r)} commit{s} {branch}..HEAD')
            return r
    return []


def _get_remote(name):
    origin = GIT.config('--get', f'remote.{name}.url')
    origin = origin and origin[0]
    if not origin:
        return

    prefix = next(p for p in ('git@', 'https://') if origin.startswith(p))
    origin = origin[len(prefix) :]
    host, user, project_git = origin.replace(':', '/').split('/')
    host_name, *_ = host.split('.')
    project, g = project_git.split('.')
    assert g == 'git'

    return host, host_name, user, project


def add_arguments(parser):
    parser.add_argument('cmd', nargs='?', default='commits', help=_HELP_CMD)


_HELP_CMD = 'Command to execute - choose from ' + ' '.join(URLS['github.com'])

if __name__ == '__main__':
    PROGRAM.start()
