# Path: src/helper_functions.py
# def grab_vector(connection, cmd, *args):
#     return [x[0] for x in connection.execute(cmd, *args).fetchall()]
# 
# def load_options(f_option_file="options_simple_connected.json"):
#     # Load the file into a string
#     try:
#         with open(f_option_file) as FIN:
#             raw_text = FIN.read()
#     except:
#         msg = "Couldn't find option file {}".format(f_option_file)
#         raise IOError(msg)
# 
#     # Parse the text as json
#     try:
#         return json.loads(raw_text)
#     except Exception as Ex:
#         msg = "Couldn't parse JSON file {}, {}".format(f_option_file, Ex)
#         raise IOError(msg)
# 
# def load_graph_database(N, check_exist=True, special=False, timeout=5):
#     ''' Given an input value of N, return a connection to the
#         cooresponding database '''
# 
#     # Build the needed directories
#     mkdir_p("database")
#     mkdir_p("database/special")
# 
#     if not special:
#         f_database = generate_database_name(N)
#     else:
#         f_database = generate_special_database_name(N)
# 
#     # Check if database exists, if so exit!
#     if check_exist and not os.path.exists(f_database):
#         err = "Database %s does not exist." % f_database
#         logging.critical(err)
#         exit()
# 
#     return sqlite3.connect(f_database, check_same_thread=False,
#                            timeout=timeout)
# 
# Path: src/invariants.py
# def convert_to_numpy(adj, N, **kwargs):
#     possible_edges = int ((N * (N + 1)) / 2)
# 
#     edge_map = np.binary_repr(adj, possible_edges)
#     edge_int = [int(x) for x in edge_map]
# 
#     idx = np.triu_indices(N)
#     A = np.zeros((N, N), dtype=np.int)
# 
#     A[idx] = edge_int
# 
#     # Works for loopless graphs only
#     A += A.T
#     return A


import logging
import argparse
import graph_tool as gt
import numpy as np
from src.helper_functions import grab_vector, load_options, load_graph_database
from src.invariants import convert_to_numpy
logging.root.setLevel(logging.INFO)

# Connect to the database
conn = helper_functions.load_graph_database(N)

# Load the list of invariants to compute
options = load_options()
invariant_names = options["invariant_function_names"]

# Check the inputs to see if they are valid queries
for func_name, val in cargs["invariant_query"]:
    if func_name not in invariant_names:
        err = "{} not a known invariant".format(func_name)
        raise KeyError(err)

    try:
        int(val)
    except Exception as ex:
        err = "{}={} is {}".format(func_name, val, ex)
        raise ValueError(err)

cmd_search = '''
SELECT adj FROM invariant_integer AS A
JOIN graph AS B ON A.graph_id = B.graph_id'''
constraints = ["{}={}".format(*items) for items in cargs["invariant_query"]]
if constraints:
    cmd_search += ' WHERE ' + ' AND '.join(constraints)
cmd_search += " LIMIT {limit} ".format(**cargs)

# Add limit at some point

# Path: src/helper_functions.py
# def grab_vector(connection, cmd, *args):
#     return [x[0] for x in connection.execute(cmd, *args).fetchall()]
# 
# def load_options(f_option_file="options_simple_connected.json"):
#     # Load the file into a string
#     try:
#         with open(f_option_file) as FIN:
#             raw_text = FIN.read()
#     except:
#         msg = "Couldn't find option file {}".format(f_option_file)
#         raise IOError(msg)
# 
#     # Parse the text as json
#     try:
#         return json.loads(raw_text)
#     except Exception as Ex:
#         msg = "Couldn't parse JSON file {}, {}".format(f_option_file, Ex)
#         raise IOError(msg)
# 
# def load_graph_database(N, check_exist=True, special=False, timeout=5):
#     ''' Given an input value of N, return a connection to the
#         cooresponding database '''
# 
#     # Build the needed directories
#     mkdir_p("database")
#     mkdir_p("database/special")
# 
#     if not special:
#         f_database = generate_database_name(N)
#     else:
#         f_database = generate_special_database_name(N)
# 
#     # Check if database exists, if so exit!
#     if check_exist and not os.path.exists(f_database):
#         err = "Database %s does not exist." % f_database
#         logging.critical(err)
#         exit()
# 
#     return sqlite3.connect(f_database, check_same_thread=False,
#                            timeout=timeout)
# 
# Path: src/invariants.py
# def convert_to_numpy(adj, N, **kwargs):
#     possible_edges = int ((N * (N + 1)) / 2)
# 
#     edge_map = np.binary_repr(adj, possible_edges)
#     edge_int = [int(x) for x in edge_map]
# 
#     idx = np.triu_indices(N)
#     A = np.zeros((N, N), dtype=np.int)
# 
#     A[idx] = edge_int
# 
#     # Works for loopless graphs only
#     A += A.T
#     return A


# Path: viewer.py
import logging
import argparse
import graph_tool as gt
import numpy as np
from src.helper_functions import grab_vector, load_options, load_graph_database
from src.invariants import convert_to_numpy

logging.root.setLevel(logging.INFO)

# Connect to the database
conn = helper_functions.load_graph_database(N)

# Load the list of invariants to compute
options = load_options()
invariant_names = options["invariant_function_names"]

# Check the inputs to see if they are valid queries
for func_name, val in cargs["invariant_query"]:
    if func_name not in invariant_names:
        err = "{} not a known invariant".format(func_name)
        raise KeyError(err)

    try:
        int(val)
    except Exception as ex:
        err = "{}={} is {}".format(func_name, val, ex)
        raise ValueError(err)

cmd_search = '''
SELECT adj FROM invariant_integer AS A
JOIN graph AS B ON A.graph_id = B.graph_id'''
constraints = ["{}={}".format(*items) for items in cargs["invariant_query"]]
if constraints:
    cmd_search += ' WHERE ' + ' AND '.join(constraints)
cmd_search += " LIMIT {limit} ".format(**cargs)

# Add limit at some point

ADJ = grab_vector(conn, cmd_search)