#!/usr/bin/lua

sqlite3 = require("lsqlite3")

---------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Functions --
---------------------------------------------------------------------------------------------------------------------------------------------------------------

function get_version(filename)
    db = sqlite3.open(filename) 
    stmt = db:prepare("SELECT * FROM SiteConfig");
    colnames = stmt:get_names();
    cnt = 1;
    local has_version = false
    while colnames[cnt] do
        if colnames[cnt] == "Version" then
            has_version = true
        end   
        cnt = cnt+1  
    end
    if has_version then
        for row in db:rows("SELECT Version FROM SiteConfig WHERE ConfigNum=1") do
            db:close()
            return row[1]
        end
    end
    db:close()
    return nil
end


function get_table_names(db)
    local names = {}
    local cnt = 0;
    for row in db:rows("SELECT name FROM sqlite_master WHERE type='table'") do
        names[cnt] = row[1];
        cnt = cnt+1
    end
    return names;
end


function copy_table(src,dest,table)
    sql="SELECT * FROM "..table
    stmt = src:prepare(sql)
   
    colnames = stmt:get_names()
    coltypes = stmt:get_types()
   
    for row in stmt:rows() do
      
        local insert_cols = ""
        local insert_vals = ""
        
        local cnt = 1  
        local first=1 
        while colnames[cnt] do
            if row[cnt] then  
                if first == 1 then
                    insert_cols = insert_cols..colnames[cnt]
                    if coltypes[cnt] == "TEXT" or coltypes[cnt] == "STRING" then
                        insert_vals = insert_vals.."\""..row[cnt].."\""
                    else
                        insert_vals = insert_vals..row[cnt]
                    end
                    first = 0
                else
                    insert_cols = insert_cols..","..colnames[cnt]
                    if coltypes[cnt] == "TEXT" or coltypes[cnt] == "STRING" then
                        insert_vals = insert_vals..",\""..row[cnt].."\""
                    else
                        insert_vals = insert_vals..","..row[cnt]
                    end
                end
            end
            cnt = cnt +1
        end
        insert="INSERT OR REPLACE INTO "..table.." ("..insert_cols..") VALUES ("..insert_vals..")"
        print(insert)
        local err = dest:exec(insert)
        if(err~=sqlite3.OK) then
            print ("sqlit3 ERR: "..dest:errmsg())
        end
    end 
end


function copy_db(src,dest)
    print("Copy function started\n")
    local table_names = {}
    table_names = get_table_names(src)
  
    local cnt = 0

    while table_names[cnt] do
        print("Copying table "..table_names[cnt])
        copy_table(src,dest,table_names[cnt])
        cnt = cnt + 1
    end  
end


function db_data_copy(src,dest)
    if src == nil or dest == nil then
        print(" Usage dbcp <src_db> <dest_db>\n")
    else
        print("Copying "..src.." to "..dest)
        db_src = sqlite3.open(src)
        db_dest = sqlite3.open(dest)
  
        if not db_src:isopen() then
            print(" Could not open source db \n")
        elseif not db_dest:isopen() then
            print(" Could not open destination db\n")
        else
            print("Databases opened OK")
            copy_db(db_src,db_dest)
            db_src:close()
            db_dest:close()
        end      
    end
end


function update_db_version(db_path, version)
    db = sqlite3.open(db_path)
    local sql = "UPDATE SiteConfig SET Version="..version
    print(sql)
    db:exec(sql)
    db:close()
end


function file_exists(filename)
    local filename = filename or "NULL"
    local file = io.open(filename, "r")
    if (file ~= nil) then
        file:close()
        return true
    else
        return false
    end
end


---------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Script start --
---------------------------------------------------------------------------------------------------------------------------------------------------------------

print("This is the rsmd post-install db upgrade script")


pkg_root = "/"

local db_skeleton = pkg_root.."usr/share/rsmd/rsmd.db" -- Database skeleton (spooky!)
local db_active = pkg_root.."var/rsm/rsmd.db" -- Active database
local db_backup = pkg_root.."var/rsm/rsmd.db.bak" -- Backup of active database
local new_version = nil -- Database skeleton version

if (file_exists(db_skeleton)) then
    new_version = get_version(db_skeleton)
else
    print("Warning: database skeleton is missing.")
    print("rsmd will have to figure things out by itself.")
    
    os.exit(0)
end

-- Make sure the directory exists before we attempt to do anything
os.execute(string.format("mkdir -p %s", pkg_root.."var/rsm"))

if (file_exists(db_active)) then
    print("Moving active database to backup.")
    os.execute(string.format("mv %s %s", db_active, db_backup))    
else
    print("No active database found.")
end

print("Copying skeleton database as new active database.")
os.execute(string.format("cp %s %s", db_skeleton, db_active))

if (file_exists(db_backup)) then
    print("Importing data from backup database into active database")
    db_data_copy(db_backup, db_active)
    update_db_version(db_active, new_version)
else
    print("Nothing to do")
end

os.exit(0)