#!/usr/bin/env python3
# coding: utf-8
import os
import sys
import argparse
from getpass import getpass
from subprocess import Popen,PIPE

# for debugging
sys.path.insert(0, os.getcwd())

import twins.twins as twins
import twins.kdb as kdb
import twins.twincal
from twins import Twins

def get_username ():
    try:
        username = open(os.path.expanduser("~/.twins-username")).read()
    except IOError:
        username = input("enter username (sXXXXXXX): ")
        with open(os.path.expanduser("~/.twins-username"), "w") as f: f.write(username)
    return username


def get_passwd (username):
    try:
        passwd = open(os.path.expanduser("~/.twins-passwd")).read()
    except IOError:
        # パスワードを~/.twins-passwordに保存する
        passwd = getpass("enter passwd: ")
        open(os.path.expanduser("~/.twins-passwd"), "w").close()
        os.chmod(os.path.expanduser("~/.twins-passwd"), 0o600)
        with open(os.path.expanduser("~/.twins-passwd"), "w") as f:
            f.write(passwd)
    return passwd

def delete_account_info (s):
    try:
        username = open(os.path.expanduser("~/.twins-username")).read()
        os.remove(os.path.expanduser("~/.twins-username"))
        os.remove(os.path.expanduser("~/.twins-passwd"))
    except:
        pass

    sys.exit("ログインエラー: " + s)


def login_twins ():
    try:
        return Twins(get_username(), get_passwd(get_username()))
    except twins.AuthError as e:
       delete_account_info(str(e))

#
#
#  サブコマンド
#
#
def stats (args):
    t = login_twins()
    print("評価\t単位数\t科目名")
    for a in t.get_achievements():
        print("%s\t%s\t%s" % (a["総合評価"], a["単位数"], a["科目名"]))


def sum (args):
    t = login_twins()
    for k,v in t.get_achievements_summary().items():
        if k == "GPA":
            print("%s:\t\t%s" % (k, v))
        else:
            print("%s:\t%s" % (k, v))


def timetable (args):
    module = args["module"]
    t = login_twins()

    try:
        html = t.get_timetable_html(module)
    except twins.RequestError:
        sys.exit("エラー: 上手くいかなかった")

    try:
        p = Popen(["w3m", "-T", "text/html"], stdin=PIPE)
        p.stdin.write(bytes(html, "utf-8"))
        p.stdin = sys.stdin
        p.wait()
    except Exception as e:
        sys.exit("エラー: " + str(e))

def reg (args):
    id = args["id"]
    t = login_twins()

    try:
        t.register_course(id)
    except twins.RequestError:
        sys.exit("履修エラー: 不正、重複またはまだ履修できない科目番号です (%s)" % id)


def unreg (args):
    id = args["id"]
    t = login_twins()

    try:
        t.unregister_course(id)
    except twins.RequestError:
        sys.exit("履修取り消しエラー: '%s'" % id)


def reged (args):
    with_table = args["table"]
    ics = args["ics"]
    t = login_twins()

    if ics:
        print(twins.twincal.generate_ics(t.get_registered_courses()))
    else:
        if with_table:
            from prettytable import PrettyTable
            x = PrettyTable(["科目番号", "単位", "学期", "曜日", "教室", "科目名"])
            x.padding_width = 1
            for c in t.get_registered_courses():
                if c is None: continue
                x.add_row([c["id"], c["credit"], c["modules"], c["periods"], c["room"], c["title"]])
            print(x)
        else:
            for c in t.get_registered_courses():
                if c is None: continue
                print("%s\t\t%s\t%s\t%s\t%s\t\t%s" % (c["id"], c["credit"], c["modules"], c["periods"], c["room"], c["title"]))


def info (args):
    id = args["id"]

    try:
        c = kdb.get_course_info(id)
    except kdb.DownloadError:
        sys.exit("failed to download Kdb database")

    if c is None:
        sys.exit("twins: no such a course: " + id)

    print("科目名:   %s"  % c["title"])
    print("科目番号: %s"  % c["id"])
    print("単位:     %s"  % c["credit"])
    print("学期:     %s"  % c["modules"])
    print("教室:     %s"  % c["room"])
    print("時限:     %s"  % c["periods"])
    print("概要:\n%s"     % c["desc"])
    print("注意事項:\n%s" % c["remarks"])


def search (args):
    with_table = args["table"]
    query = args["query"]

    try:
        k = kdb.Kdb()
    except kdb.DownloadError:
        sys.exit("failed to download Kdb database")

    if with_table:
        from prettytable import PrettyTable
        x = PrettyTable(["科目番号", "単位", "学期", "曜日", "教室", "科目名"])
        x.padding_width = 1
        for c in k.search(query):
            if c is None: continue
            x.add_row([c["id"], c["credit"], c["modules"], c["periods"], c["room"], c["title"]])
        print(x)
    else:
        print("%s\t%s\t%s\t%s\t\t%s" % ("科目番号", "単位", "学期", "曜日", "科目名"))
        for c in k.search(query):
            if c is None: continue
            print("%s\t\t%s\t%s\t%s\t\t%s" % (c["id"], c["credit"], c["modules"], c["periods"], c["title"]))


def main ():
    parser = argparse.ArgumentParser(description="Command-line interface to TWINS")
    subparsers = parser.add_subparsers()

    parser_stats = subparsers.add_parser("stats", help="成績開示")
    parser_stats.set_defaults(func=stats)

    parser_sum = subparsers.add_parser("sum", help="累計成績要約 (履修単位数, 修得単位数, GPA)")
    parser_sum.set_defaults(func=sum)

    parser_reged = subparsers.add_parser("reged", help="履修登録済み科目一覧")
    parser_reged.add_argument("--table", action="store_true", help="人にやさしい表示")
    parser_reged.add_argument("--ics", action="store_true", help="TwinCalを使ってICS形式で出力")
    parser_reged.set_defaults(func=reged)

    parser_reg = subparsers.add_parser("reg", help="履修登録")
    parser_reg.add_argument("id", help="科目番号")
    parser_reg.set_defaults(func=reg)

    parser_unreg = subparsers.add_parser("unreg", help="履修取り消し")
    parser_unreg.add_argument("id", help="科目番号")
    parser_unreg.set_defaults(func=unreg)

    parser_info = subparsers.add_parser("info", help="科目情報")
    parser_info.add_argument("id", help="科目番号")
    parser_info.set_defaults(func=info)

    parser_search = subparsers.add_parser("search", help="科目検索")
    parser_search.add_argument("query", help="文字列")
    parser_search.add_argument("--table", action="store_true", help="人にやさしい表示")
    parser_search.set_defaults(func=search)

    parser_timetable = subparsers.add_parser("timetable", help="時間割を表示")
    parser_timetable.add_argument("module", help="モジュール名 (例: 秋A)")
    parser_timetable.set_defaults(func=timetable)

    args = parser.parse_args()

    if not "func" in args:
       parser.parse_args("--help".split())

    args.func(vars(args))

if __name__== "__main__":
    try:
        main()
    except KeyboardInterrupt:
        sys.exit("aborted.")
