#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Clone all gists of GitHub user with given username.

Clones all gist repos into the current directory, using the gist id as the
directory name. If the directory already exists as a git repo, try to perform a
'git pull' in it.

"""

import argparse
import sys
from os.path import exists, join
from subprocess import CalledProcessError, check_call

import requests


def main(args=None):
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument(
        "-p", "--page", type=int, metavar="PAGE", help="Fetch only page PAGE from list  of Gists"
    )
    ap.add_argument(
        "--per-page", type=int, metavar="NUM", default=100, help="Fetch NUM gists per page"
    )
    ap.add_argument(
        "-s", "--ssh-url", action="store_true", help="Clone gists using SSH URL instead of HTTPS"
    )
    ap.add_argument(
        "-v", "--verbose", action="store_true", help="Run git commands with verbose messages"
    )
    ap.add_argument("username", help="GitHub username")
    ap.add_argument("token", nargs="?", help="GitHub auth token")
    args = ap.parse_args(args)

    page = args.page

    while True:
        if page is None:
            page = 1

        print(f"Fetching page {page} of list of Gists of user {args.username}...")
        url = "https://api.github.com/users/{}/gists".format(args.username)
        headers = {"Authorization": "token " + args.token} if args.token else {}
        resp = requests.get(url, headers=headers, params={"per_page": args.per_page, "page": page})

        if resp.status_code == 200:
            for gist in resp.json():
                gistid = gist["id"]

                try:
                    if exists(join(gist["id"], ".git")):
                        print(f"Updating gist {gistid} via 'git pull'...")
                        check_call(["git", "pull", "-v" if args.verbose else "-q"], cwd=gistid)
                    else:
                        url = gist["git_pull_url"]

                        if args.ssh_url:
                            url = url.replace("https://gist.github.com/", "git@gist.github.com:")

                        print(f"Cloning Gist from {url}...")
                        check_call(["git", "clone", "-v" if args.verbose else "-q", url])
                except CalledProcessError:
                    print(f"*** ERROR cloning/updating gist {gistid}. Please check output.")
                except KeyboardInterrupt:
                    break

            if 'rel="next"' in resp.headers.get("link", ""):
                page += 1
            else:
                break
        else:
            return "Error reponse: {}".format(req.json().get("message"))

        if args.page:
            break


if __name__ == "__main__":
    sys.exit(main() or 0)