#!/usr/bin/env python

"""

Usage:
    gistup publish
    gistup scripts
    gistup open
    gistup --help

Details:
    publish                  - publishes CWD to a gist (excluding dot files)
    scripts                  - generates html script tags for gist files
    open                     - opens the gist in default web browser

Flags:
    --help                   - displays this help text

"""

import yaml
import argparse
from termcolor import colored
from github import Github
from github import InputFileContent
from github.GithubObject import NotSet
from subprocess import call
from os import listdir, getcwd
from os.path import isfile, join, expanduser, exists

USER_FILE = expanduser('~/.gistup.user.yml')
SETTINGS_FILE = join(getcwd(), '.gistup.yml')
SCRIPT_TAG = '<script src="{html_url}.js"></script>'
SCRIPT_TAG_WITH_FILE = '<script src="{html_url}.js?file={file}"></script>'


def load_yaml(path):
    with open(path) as f:
        return yaml.load(f)


def allowed(f):
    return isfile(f) and f[0] is not '.'


def get_file_contents(path):
    with open(path, "rU") as f:
        return InputFileContent(f.read())


def get_files_dict(d=getcwd()):
    file_dict = {}
    for f in listdir(d):
        if allowed(f):
            file_dict[f] = get_file_contents(f)
    return file_dict


def login():
    token = raw_input('Enter personal access token: ').strip()
    github = Github(token)
    email = github.get_user().email
    print 'logged in as {email}'.format(email=email)
    print 'saving credentials to {path}'.format(path=USER_FILE)
    with open(expanduser(USER_FILE), 'w+') as f:
        f.write('id: {token}\nemail: {email}'.format(
            token=token,
            email=email
        ))


def init(user):
    description = raw_input('Enter Gist description: ').strip()
    public = raw_input('Do you want this to be public [y/n]: ').strip().lower() is 'y'
    default_file = InputFileContent('published using gistup')
    gist = user.create_gist(public=public,
                            description=description,
                            files={'zinit.md': default_file})

    print gist.html_url

    with open(SETTINGS_FILE, 'w+') as f:
        f.write('id: {id}\ndescription: {desc}'.format(id=gist.id,
                                                       desc=description))


def publish(gist, settings):
    gist.edit(settings.get('description', NotSet), get_files_dict())


def scripts(gist):
    html_url = gist.html_url
    print colored('All in one', 'yellow')
    print SCRIPT_TAG.format(html_url=html_url)
    print colored('Indavidual Files', 'yellow')
    for k, v in gist.files.items():
        print SCRIPT_TAG_WITH_FILE.format(html_url=html_url, file=k)


def main():

    if not exists(USER_FILE):
        print colored('You need to login first', 'green')
        login()

    credentials = load_yaml(USER_FILE)
    github = Github(credentials.get('id'))

    if not exists(SETTINGS_FILE):
        print colored('could not locate .gistup.yml in CWD', 'yellow')
        init(github.get_user())

    settings = load_yaml(SETTINGS_FILE)

    gist = github.get_gist(settings.get('id'))

    parser = argparse.ArgumentParser(prog='gistup a CLI tool to publish gists')
    parser.add_argument('command', help='available commands [publish|scripts|open]')
    args = parser.parse_args()
    command = args.command.strip()

    if command == 'publish':
        publish(gist, settings)
    elif command == 'scripts':
        scripts(gist)
    elif command == 'open':
        call(['open', gist.html_url])
    else:
        parser.print_help()

if __name__ == '__main__':
    main()
