#!/usr/bin/env python
from __future__ import print_function
import os
import argparse
from netrc import netrc
from hashlib import md5

from tucan import get_grades
import sqlite3


def mail(recipient, subject, body):
    import subprocess

    proc = subprocess.Popen(["mail", "-s", subject, recipient],
                            stdin=subprocess.PIPE)
    body = body.encode('utf-8')
    proc.stdin.write(body)
    print(body)
    proc.stdin.close()


def notify(notification_msg):
    from subprocess import Popen

    Popen(['notify-send', notification_msg])


def init_db(cursor):
    cursor.execute("CREATE TABLE IF NOT EXISTS grades ("
                   "   id text PRIMARY KEY,"
                   "   subject text NOT NULL,"
                   "   date text NOT NULL,"
                   "   result_no text,"
                   "   result_str text"
                   ");")

def update_db(db, grades):
    conn = sqlite3.connect(db)
    cursor = conn.cursor()

    init_db(cursor)
    new_grades = []
    for grade in grades:
        cursor.execute("SELECT id, subject, date, result_no, result_str FROM grades WHERE id=?;",(grade.id,))
        row = cursor.fetchone()

        if row is None:
            # Add grade to data base and add it to new grades
            cursor.execute("INSERT INTO grades (id, subject, date, result_no, result_str) VALUES (?,?,?,?,?);",
                           (grade.id, grade.subject, grade.date, grade.result_no, grade.result_str))
            new_grades.append(grade)

        elif row[3] != grade.result_no:
            # Only the result was updated, so update the database entry and add grade to new grades
            cursor.execute("UPDATE grades SET result_no=?, result_str=? WHERE id=?;",
                           (grade.result_no, grade.result_str, grade.id))
            new_grades.append(grade)

    # Close DB session
    conn.commit()
    conn.close()
    return new_grades


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="TUCaN CLI",
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("--mail", "-m", type=str,
                        help="send email to this address on changes")
    parser.add_argument("--db", type=str,
                        default=os.path.expanduser("/db/.grades.db"),
                        help="database file")
    parser.add_argument("--new", help="print only new grades", action="store_true")
    parser.add_argument("--notify", "-n", action="store_true",
                        help="send desktop notification on new grades")
    parser.add_argument("--json", "-j", help="output json", action="store_true")
    parser.add_argument("--username", "-u", help="set username")
    parser.add_argument("--password", "-p", help="set password")
    args = parser.parse_args()

    grades = get_grades(args.username, args.password)
    if len(grades) > 0:
        if args.mail:
            new_grades = update_db(args.db, grades)
            if len(new_grades) > 0:
                msg = os.linesep.join([g.subject + ": " + g.result_no for g in new_grades])
                if args.mail:
                    mail(args.mail, "New Grade(s) in TUCaN", msg)
                elif args.notify:
                    notify(msg)
                else:
                    print(msg)
        else:
            if args.json:
                import json

                print(json.dumps(list(grades)))
            else:
                for grade in grades:
                    print(grade[0] + ": " + grade[2])
    else:
        msg = "No grades for the current semester"
        print(msg)
