#!/usr/bin/env python

from __future__ import division
from __future__ import print_function

import argparse
import csv
import os
import sys

import github

def main(argv):
    args = _init_args(argv)
    gh = _init_gh(args)
    _search(gh, args)

def _init_args(argv):
    p = argparse.ArgumentParser()
    p.add_argument(
        "-s", "--search", default="tensorflow",
        help="Search term (default is 'tensorflow')")
    p.add_argument(
        "-o", "--order-by", default="stars",
        choices=('stars', 'forks', 'updated'),
        help=(
            "How to order results (choices are 'stars', "
            "'forks', and 'updated'; default is 'stars')"))
    p.add_argument(
        "-p", "--pages", type=int, default=1,
        help="Number of pages to process (default is 1)")
    p.add_argument(
        "-t", "--access-token",
        help="Access token (default is GITHUB_ACCESS_TOKEN env)")
    return p.parse_args()

def _init_gh(args):
    return github.Github(_access_token(args))

def _access_token(args):
    if args.access_token:
        return args.access_token
    try:
        return os.environ["GITHUB_ACCESS_TOKEN"]
    except KeyError:
        raise SystemExit(
            "gh-search: specify either --access-token or define "
            "GITHUB_ACCESS_TOKEN")

def _search(gh, args):
    csv_out = csv.writer(sys.stdout)
    csv_out.writerow(csv_header)
    result = gh.search_repositories(args.search, sort=args.order_by)
    result_pages = result.totalCount
    for i in range(min(args.pages, result_pages)):
        page = result.get_page(i)
        for repo in page:
            sys.stderr.write(repo.full_name + "\n")
            csv_out.writerow(_repo_csv_row(repo))
            sys.stdout.flush()

csv_header = (
    "name",
    "description",
    "url",
    "stars",
    "forks",
    "contributors",
    "issues",
    "pulls",
    "releases",
    "watchers",
    "commits_1_mos",
    "commits_3_mos",
    "commits_6_mos",
    "commits_12_mos",
)

def _repo_csv_row(repo):
    commits = repo.get_stats_participation().all
    return (
        repo.full_name,
        repo.description,
        repo.html_url,
        repo.stargazers_count,
        repo.forks,
        repo.get_contributors().totalCount,
        repo.get_issues().totalCount,
        repo.get_pulls().totalCount,
        repo.get_releases().totalCount,
        repo.watchers_count,
        _commit_count(commits, 4),
        _commit_count(commits, 13),
        _commit_count(commits, 26),
        _commit_count(commits, 52),
    )

def _commit_count(commits, weeks):
    weeks = min(weeks, len(commits))
    return sum(commits[-weeks:])

if __name__ == "__main__":
    main(sys.argv)
