import prologue, prologue/middlewares/staticfile, prologue/middlewares/cors, std/json, sysrandom, asyncdispatch, std/strutils, db_connector/db_sqlite, std/asyncnet

const key_len = 128 
const refer_len = 16
const debug = true

let db = open("real.db", "", "", "")

db.exec(
sql"""CREATE TABLE IF NOT EXISTS keys(
    referral VARCHAR(255) NOT NULL,
    key      VARCHAR(255) NOT NULL,
    ip       VARCHAR(255) NOT NULL
)""")

proc index*(ctx: Context) {.async.} = 
    for x in db.fastRows(sql"SELECT * FROM keys"):
        echo x
    await ctx.staticFileResponse("public/index.html", "")

proc ip_exists*(ip: string): bool = 
    return len(db.getAllRows(sql"SELECT * FROM keys WHERE ip=?", ip)) != 0

proc referral_exists*(refer: string): bool =
    let results = db.getAllRows(sql"SELECT * FROM keys WHERE referral=?", refer)
    return len(results) != 0

proc generate_referral*(key, referral: var string, ip: string): void = 
    key = "K-" & getRandomString(key_len)
    referral = "R-" & getRandomString(refer_len)
    db.exec(sql"INSERT INTO keys (referral, key, ip) VALUES (?, ?, ?)", referral, key, ip)

proc gentry*(ctx: Context) {.async.} =
    var key: string = ""
    var referral: string = ""
    var err: bool = true
    if (not ctx.request.hasHeader("referral") or 
        not referral_exists($ctx.request.getHeader("referral")) or
        ip_exists(ctx.request.hostName)) and not debug:
        err = true
    else:
        generate_referral(key,referral, ctx.request.hostName)
        err = false

    var info = %* 
        {
            "referral": referral,
            "key": key,
            "err": err
        }

    resp jsonResponse(info)

var app = newApp()

app.use(CorsMiddleware(allowOrigins = @["*"], allowHeaders = @["*"], allowMethods = @["*"])) 
app.use(staticFileMiddleware("./public"))
app.addRoute("/", index)
app.addRoute("/entry", gentry)
app.run()