#!/usr/bin/env python3
"""
A small utility for making gists from the command line
"""

import os
import sys
import json
import argparse
import pyperclip
import requests

from os.path import isabs, expanduser
from getpass import getpass

BASE_DIR = os.getcwd()
ENDPOINT = "https://api.github.com/gists"
SECRETS_FILE = os.path.expanduser("~/.mkgist.conf")


def create_secrets_file():
    print("(First use) Please retreive a personal access token")
    print("Link: https://github.com/settings/tokens/new")
    print("It must have the 'gist' scope")

    secrets = {}
    secrets["access_token"] = getpass("Token: ")

    with open(SECRETS_FILE, "w") as secrets_file:
        secrets_file.write(json.dumps(secrets))
        print("Done!")
        return secrets


def process_files(arg_filenames, request_data):
    filenames = []
    for filename in arg_filenames:
        if "/" not in filename:
            name = filename
        else:
            name = filename[filename.rfind("/") + 1 :]
        filenames.append(name)

        if not "files" in request_data:
            request_data["files"] = {name: {"content": None}}
        else:
            request_data["files"][name] = {"content": None}

        try:
            if isabs(expanduser(filename)):
                with open(expanduser(filename), "r") as content_file:
                    request_data["files"][name]["content"] = content_file.read()
            else:
                with open("{}/{}".format(BASE_DIR, filename), "r") as content_file:
                    try:
                        request_data["files"][name]["content"] = content_file.read()
                    except:
                        print("Failed while reading file {}".format(name))
                        exit(1)
        except IOError:
            print("An error occured when opening file {}".format(filename))
            exit(1)

    return request_data, filenames


def process_stdin(request_data):
    print("Reading from STDIN. If not piping, press Ctrl-D on a newline to finish.")

    request_data["files"] = {}
    request_data["files"]["out"] = {"content": None}
    request_data["files"]["out"]["content"] = sys.stdin.read()

    return request_data


def handle_raw(as_json, args, filenames):
    if args.filenames:
        if len(filenames) > 1:
            for name in filenames:
                print("{}:\n{}\n".format(name, as_json["files"][name]["raw_url"]))
            exit(1)
        else:
            url = as_json["files"][args.filenames[0]]["raw_url"]
    else:
        url = as_json["files"]["out"]["raw_url"]

    return url


def process_result(res, args, filenames):
    try:
        as_json = res.json()
        if "html_url" in as_json:
            if args.raw:
                url = handle_raw(as_json, args, filenames)
            else:
                url = as_json["html_url"]

            if args.nocopy:
                print(url)
            else:
                pyperclip.copy(url)
                pyperclip.paste()
                print("Gist URL copied to clipboard.")
        else:
            print(as_json["message"].rstrip())
    except:
        print("An error occured")


def run(args):
    if args.public:
        request_data = {"public": True}
    else:
        request_data = {"public": False}

    if args.description:
        request_data["description"] = args.description

    if args.filenames:
        request_data, filenames = process_files(args.filenames, request_data)
    else:
        filenames = []
        request_data = process_stdin(request_data)

    res = requests.post(
        ENDPOINT,
        data=json.dumps(request_data),
        headers={"Authorization": "token {}".format(SECRETS["access_token"])}
    )

    process_result(res, args, filenames)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Utility for making anonymous gists")
    parser.add_argument(
        "filenames", help="Name of file(s) to make into gist", nargs="*"
    )
    parser.add_argument("-d", "--description", help="description for gist")
    parser.add_argument("-r", "--raw", action="store_true", help="fetch raw link")
    parser.add_argument(
        "-n",
        "--nocopy",
        action="store_true",
        help="print result url to screen instead of overwriting clipboard",
    )
    parser.add_argument("-p", "--public", action="store_true", help="make gist public")
    args = parser.parse_args()

    try:
        # Load secrets, which contains access token
        try:
            SECRETS = json.load(open(SECRETS_FILE))
            if not "access_token" in SECRETS:
                SECRETS = create_secrets_file()
        except FileNotFoundError:
            SECRETS = create_secrets_file()

        run(args)
    except KeyboardInterrupt:
        print("Exiting")
        exit(0)
