#!/usr/bin/env python

import argparse
import yaml
import sh
import os
from urlparse import urlparse
from os.path import splitext, basename, exists
from os import makedirs
from semantic_version import Version, Spec, validate

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def update(args):
    dependency_file = args.dependency_file
    clone_path = args.clone_path

    requirements = []

    try:
        with open(dependency_file, 'r') as stream:
            try:
                requirements = yaml.load(stream)
            except yaml.YAMLError as exc:
                print(exc)
    except IOError as e:
        print(e)
        exit(e.errno)

    git = sh.git.bake(_cwd=clone_path, _tty_out=False)

    if not exists(clone_path):
        makedirs(clone_path)

    for requirement in requirements:
        if 'src' not in requirement:
            print 'no src found'
            break
        else:
            src = requirement['src']

        if 'name' in requirement:
            name = requirement['name']
        else:
            disassembled = urlparse(requirement['src'])
            name, _ = splitext(basename(disassembled.path))

        branch = 'master'
        version = None

        if 'version' in requirement:
            version = requirement['version']

        if 'branch' in requirement:
            branch = requirement['branch']

        repo = sh.git.bake(_cwd=clone_path + '/' + name, _tty_out=False)

        if not exists(clone_path + '/' + name):
            print 'Cloning: ' + name + ' into ' + clone_path + '/' + name
            git.clone(src, name)
        else:
            print 'Pulling: ' + name + ' into ' + clone_path + '/' + name
            repo.checkout(branch)

        repo.pull('--tags')

        versions = []

        for tag in repo.tag('-l',_tty_out=False).split('\n'):
            if tag and validate(tag):
                versions.append(Version(tag))

        if version:
            spec = Spec(version)
            selected_version = spec.select(versions)
            if selected_version is None:
                print bcolors.FAIL + 'No suitable version: ' + version + ' found for ' + name + bcolors.ENDC
            else:
                versionList = []
                for version in versions:
                    versionList.append(str(version))
                print bcolors.OKGREEN + 'Selecting version: ' + str(selected_version) + ' for ' + name + bcolors.ENDC + ' from ' + ', '.join(versionList)
                repo.checkout('tags/' + str(selected_version), _tty_out=False)


parser = argparse.ArgumentParser(description='Git Out Of Hell - Language agnostic semantic versioner using git tags')

parser.add_argument(
    '--dependency_file',
    default='gooh.yml',
    help='Config yaml which holds all dependencies\n (default=gooh.yml)'
)

parser.add_argument(
    '--clone_path',
    default='roles',
    help='Path where the dependencies should be cloned (default=roles)'
)

update(parser.parse_args())

exit(0)
