#!/usr/bin/env python3

from util import randomSAT
from util import kSAT
import util.script as scriptUtils
import pymongo
import ssl

def main():
    args = __parseArguments()

    dbContext = __getDBContext(args["dbConfigPath"])

    __generateExperiment(args, dbContext)

    dbContext["client"].close()

def __generateExperiment(args, dbContext):
    experimentScope = __prepareExperimentScope(args)

    for i in range(args["instances"]):
        sat = randomSAT.generateRandomKSAT(args["clauses"],
                                           args["variables"],
                                           args["variablesPerClause"])
        
        instanceId = dbContext["instances"].insert_one(sat.writeJSONLike()).inserted_id
        
        experimentScope["instances"].append(instanceId)

    dbContext["experimentScopes"].insert_one(experimentScope)



def __prepareExperimentScope(args):
    experimentScope = {}
    experimentScope["instances"] = []
    
    description =  "This experiment contains %d instances " % args["instances"]
    description += "each with %d clauses, %d variables " % (args["clauses"], 
                                                            args["variables"])
    description += ("and %d variables per clause (c/v = %.2f)"
                    %(args["variablesPerClause"],
                      float(args["clauses"]) / float(args["variables"])))

    experimentScope["description"] = description
    
    experimentScope["_id"] = args["experimentId"].strip()

    return experimentScope


def __getDBClient(dbConfigPath):
    dbConf = scriptUtils.readConfig(dbConfigPath)
    dbConf["CONNECTION"]

    return pymongo.MongoClient(
            "mongodb://%s:%s@%s:%s/%s"
            % ( dbConf["CONNECTION"]["user"],
                dbConf["CONNECTION"]["pw"],
                dbConf["CONNECTION"]["url"],
                dbConf["CONNECTION"]["port"],
                dbConf["CONNECTION"]["database"]), 
            ssl=True, 
            ssl_cert_reqs=ssl.CERT_NONE)

    
def __getDBContext(dbConfigPath):
    dbContext = {}
    
    dbContext["client"] = __getDBClient(dbConfigPath)
    dbContext["db"] = dbContext["client"]["experiments"]
    dbContext["instances"] = dbContext["db"]["instances"]
    dbContext["experimentScopes"] = dbContext["db"]["experiment_scopes"]

    return dbContext

def __parseArguments():
    parser = scriptUtils.ArgParser()

    parser.addArg(alias="instances", shortFlag="i", longFlag="instances",
                  help="number of random kSAT instances", type=int)

    parser.addArg(alias="variables", shortFlag="v", longFlag="variables",
                  help="number of variables in the ksat instances", type=int)

    parser.addArg(alias="clauses", shortFlag="c", longFlag="clauses",
                  help="number of clauses in the ksat instances", type=int)

    parser.addArg(alias="variablesPerClause", shortFlag="vpc",
                  longFlag="variables_per_clause",
                  help="variables per clause in the kSAT instances", type=int,
                  default=3)

    parser.addArg(alias="dbConfigPath", shortFlag="d", longFlag="db_config",
                  help="path to the database config file", type=str,
                  default="database.config")

    parser.addArg(alias="experimentId", shortFlag="id", longFlag="experiment_id",
                  help="the name or id of the experiment", type=str)


    return parser.parse()

if __name__ == "__main__":
    main()
