#!/usr/bin/python3

import os
from sqlite3 import connect

def create_db():

    target = 'cremona.db'

    print("Creating database {0}".format(target))
    if os.path.exists(target):
        os.remove(target)

    con = connect(target)

    con.execute('CREATE TABLE t_class(conductor INTEGER,'
                ' class TEXT PRIMARY KEY, rank INTEGER, L REAL, deg INTEGER)')
    con.execute('CREATE TABLE t_curve(class TEXT,'
                ' curve TEXT PRIMARY KEY, eqn TEXT UNIQUE,'
                ' gens TEXT, tors INTEGER, cp INTEGER,'
                ' om REAL, reg REAL, sha)')
    con.execute('CREATE INDEX i_t_class_conductor ON t_class(conductor)')
    con.execute('CREATE INDEX i_t_curve_class ON t_curve(class)')

    return con

def populate_allcurves(con):
    print('Inserting all curves')
    for filename in sorted(os.listdir('allcurves')):
        class_data = []
        curve_data = []
        with open(os.path.join('allcurves', filename)) as fich:
            print('\tConsidering {0}'.format(filename))
            for line in fich.readlines():
                N, iso, num, ainvs, r, tor = line.split()
                cls = N+iso
                cur = cls+num
                if num == "1":
                    class_data.append((N,cls,r))
                curve_data.append((cur,cls,ainvs,tor))
        con.executemany('INSERT INTO t_class (conductor,class,rank)'
                        ' VALUES (?,?,?)', class_data)
        con.executemany('INSERT INTO t_curve (curve,class,eqn,tors)'
                        ' VALUES (?,?,?,?)', curve_data)
        con.commit()

def populate_allbsd(con):
    print('Inserting all BSD')
    for filename in sorted(os.listdir('allbsd')):
        # why, oh why? There's a single problematic file...
        if not filename.startswith('allbsd'):
            break
        class_data = []
        curve_data = []
        with open(os.path.join('allbsd', filename)) as fich:
            print('\tConsidering {0}'.format(filename))
            for line in fich.readlines():
                N, iso, num, eqn, rank, tor, cp, om, L, reg, sha  = line.split()
                cls = N+iso
                if num == "1":
                    class_data.append((L,cls))
                curve_data.append((cp,om,reg,eval(sha),cls+num))
        con.executemany("UPDATE t_class SET L=? WHERE class=?", class_data)
        con.executemany("UPDATE t_curve SET cp=?,om=?,reg=?,sha=? WHERE "
                        " curve=?", curve_data)
        con.commit()

def populate_allgens(con):
    print('Inserting all gens')
    for filename in sorted(os.listdir('allgens')):
        curve_data = []
        with open(os.path.join('allgens', filename)) as fich:
            print('\tConsidering {0}'.format(filename))
            for line in fich.readlines():
                v = line.split()
                gens = '['+','.join(v[6:6+int(v[4])]).replace(':',',')+']'
                curve_data.append((gens,''.join(v[:3])))
        con.executemany("UPDATE t_curve SET gens=? WHERE curve=?",
                        curve_data)
        con.commit()

def populate_degphi(con):
    print('Inserting all degphi')
    for filename in sorted(os.listdir('degphi')):
        class_data = []
        with open(os.path.join('degphi', filename)) as fich:
            print('\tConsidering {0}'.format(filename))
            for line in fich.readlines():
                N, iso, num, degree, primes, curve = line.split()
                class_data.append((degree,N+iso))
        con.executemany('UPDATE t_class SET deg=? WHERE class=?',
                        class_data)
        con.commit()

def repack(db):
    print('Repacking the database')
    con.execute('VACUUM')
        
if __name__ == '__main__':
    con = create_db()
    populate_allcurves(con)
    populate_allbsd(con)
    populate_allgens(con)
    populate_degphi(con)
    repack(con)
    con.close()
