#!/usr/bin/env python3

import os
import sys
import subprocess
from threading import Thread
import gt.sources

def die(*args, **kwargs):
    kwargs['file']=sys.stderr
    print("ERROR:", *args, **kwargs)
    sys.exit(-1)


GITCMD = None

for cmd in os.environ['PATH'].split(":"):
    cmd = os.path.join(cmd, "git")
    if os.path.exists(cmd):
        GITCMD = cmd

if not GITCMD:
    die('Could not find git in PATH, please ensure it is installed.')

CFG_FILE = os.path.join(os.environ['HOME'], '.gtrc')

def assert_existence(repos):
    for src, repo in repos:
        if repo not in [ r[0] for r in src.repos ]:
            die('%s/%s does not exist.' % (src.name, repo))

#Returns a list of tuples of the form (<GitSource>, <Repo Name>)

def parse_repos(args):
    repos = []
    source_repos = {}

    for repo in args:
        if '/' not in repo:
            die('%s must be of the form <source>/<repo name>' % repo)

        src, name = repo.split('/')
        if src not in g_sources:
            die('%s is not a valid git source.' % src)

        repos.append((g_sources[src], name))

    return repos

def init(args):
    public = False
    if args[0] == '-p' or args[0] == '--public':
        args.pop(0)
        public = True

    if len(args) != 1:
        print('Usage: gt init [-p | --public] <git source>/<repo>')
        exit(1)

    src, repo = parse_repos(args)[0]

    if os.path.exists('.git'):
        die('.git already exists, refusing to initialize.')

    create((['-p'] if public else []) + args)

    rc = subprocess.call([GITCMD, 'init'])
    if rc != 0:
        die('git process failed, aborting.')

    loc = src.git_url(repo)
    print('Setting %s as origin' % loc)
    rc = subprocess.call([GITCMD, 'remote', 'add', 'origin', loc])
    if rc != 0:
        die('git process failed, aborting.')

def delete(args):
    if len(args) == 0:
        die('Usage: gt create <source>/<repo name>...')

    repos = parse_repos(args)
    assert_existence(repos)

    for src, repo in repos:
        print(src.name + '/' + repo)

    r = input('The repos listed above will be deleted type YES to confirm: ')
    if r != 'YES':
        print('ABORTING')
        exit(1)

    for src, repo in repos:
        print('Deleting %s/%s' % (src.name, repo))
        src.delete(repo)

def create(args):
    private = True

    if args[0] == '--public' or args[0] == '-p':
        args.pop(0)
        private = False

    if len(args) == 0:
        die('Usage: gt create [-p|--public] <source>/<repo name>...')

    for src,repo in parse_repos(args):
        print('Creating %s repo %s/%s' % ('private' if private else 'public', src.name, repo))
        src.create(repo, is_private=private)

def ls(args):
    if len(args) != 1:
        die('Usage: gt ls [ \'*\' | <source>... ]')

    if args[0] == '*':
        args = g_sources.keys()

    for src in args:
        if src not in g_sources:
            die('%s is not a valid git source.' % src)

    threads = []
    results = {}

    def _(src):
        results[src] = g_sources[src].repos

    for src in args:
        t = Thread(target=_, args=(src,))
        threads.append(t)

    for t in threads:
        t.start()
    for t in threads:
        t.join()

    max_ = 0
    for src,repos in results.items():
        for repo,_ in repos:
            l = len('%s/%s' % (src,repo))
            if l > max_:
                max_ = l

    for src,repos in results.items():
        for repo,private in repos:
            print('%-*s %s' % (max_, '%s/%s' % (src, repo), 'private' if private else 'public'))
        

def path(args):
    if len(args) == 0:
        die('Usage: gt path <git source/repo>...')

    for src, repo in parse_repos(args):
        print(src.git_url(repo))

def clone(args):
    if len(args) != 1:
        print('Usage: gt clone <git source/repo>')

    src, repo = parse_repos(args)[0]

    git_url = src.git_url(repo)
    os.execl(GITCMD, GITCMD, 'clone', git_url)


#Main

usage = 'Usage: gt <ls|create|rm|clone> [args]'

if len(sys.argv) < 2:
    die(usage)
    
target = sys.argv[1]
args = sys.argv[2:]

commands = {
        'ls': ls,
        'create': create,
        'delete': delete,
        'rm': delete,
        'clone': clone,
        'path': path,
        'loc': path,
        'init': init,
}
if target not in commands:
    die('ERROR: %s is not a valid command.' % target)

g_sources = gt.sources.get_sources('%s/.gtrc' % os.getenv('HOME'))
commands[target](args)
