local ss = analiz.libs.serv
local lfs = require "lfs"
local fileserv = CreateFileServ()
local tick = CreateTimeServ()

local function GetRootTempDir_()
    ss.e("GETENV_PARAM prospero_temp PROSPERO_TEMP")
    local tmp = ss.g("prospero_temp")
    if tmp ~= "" then return tmp end
    -- default temp
    return ss.b("$(temp)")
end

if GetRootTempDir == nil then GetRootTempDir = GetRootTempDir_ end
ss.l("load_fa_schema_params.lua")
-- auto update update every 7 days
local THRESHOLD_DT = "7d"
-- local THRESHOLD_DT="6h"
-- local THRESHOLD_DT="1s"

local function getThreshold_(val)
    local t = val:sub(val:len(), val:len())
    local v = math.floor(analiz:tonumber(val:sub(1, val:len() - 1)))
    if t == "s" then return v end -- sec
    if t == "m" then return v * 60 end -- min
    if t == "h" then return v * 60 * 60 end -- hour
    if t == "d" then return v * 24 * 60 * 60 end -- day
    return v
end

local function loadImpl_()
    if false then
        return {a = 1, b = 2, c = 3, d = "teststring123456789123"}, ""
    end
   local gps = global_prospero_setting
    if gps.FA_SCHEMA_PARAMS_stub ~= nil then
        return global_prospero_setting.FA_SCHEMA_PARAMS_stub, ""
    end
    if gps.options.queue_engine~=nil then 
     if gps.options.queue_engine.engine=="msbroker" then 
         return {a = 1, b = 2, c = 3, d = "teststring123456789123"}, ""
     end
    end


    local schema = global_oracle_setting_local.nc_schema
    if schema ~= "" then schema = schema .. "." end
    ss.l("load_fa_schema_params.loadImpl_.start")
    ss.e("CREATE_OR_CLEAR_STRING_MAP ora_meta_params")
    ss.e(
        "set_param sql select PARAM_NAME as NAME , PARAM_VALUE AS VALUE from " ..
            schema .. "FA_SCHEMA_PARAMS")
    ss.e("echo FA_SCHEMA_PARAMS_sql:$(sql)")
    ss.e(
        "ANALIZ_SAFE_EXECUTE tmp_r tmp_e  ADD_MAP_FROM_SQL_V1  ora_meta_params ora_mq NAME VALUE $(sql)")
    ss.e("SHOW_STRING_MAP ora_meta_params")
    local emessage = ss.g("tmp_e")
    if emessage ~= "" then
        ss.l("failed:" .. emessage)
        ss.l("sql:" .. ss.g("sql"))
    end

    ss.l("load_fa_schema_params.loadImpl_.end")
    return ss.map2obj("ora_meta_params"), emessage
end

local function get_mod_dt_(f)
    local attr = lfs.attributes(f, {"modification"})
    if attr == nil then return {modification = 0} end
    return attr
end

-- ------------
local function load_from_file_(cacheio)
    local f = io.open(cacheio, "rb")
    if f == nil then return nil end
    local body = f:read("all")
    f:close()
    return body
end
-- ------------
local function save_to_file_(cacheio, body)
    ss.l("save_to_file_:" .. cacheio)
    local f = io.open(cacheio, "wb")
    if f == nil then
        ss.l("save_to_file_ failed save to file:" .. cacheio)
        return
    end
    f:write(body)
    f:close()
    ss.l("save_to_file_:ok")
end

function ret2str(r)
    if r == nil then return "nil" end
    if r == true then return "true" end
    if r == false then return "false" end
    return "" .. r
end
function DeleteFile(fn)
    ss.l("DeleteFile:" .. fn)
    for i = 1, 20 do
        local res, emessage = os.remove(fn)
        ss.l("DeleteFile." .. i .. "ret:" .. ret2str(res) .. " emessage:" ..
                 ss.def(emessage, "nil"))
        if not (fileserv:FileExists(fn)) then break end
        ss.e("sleep sec 1")
    end
    -- ss.a(1)
    --  analiz:set("tmp",fn)
    --  analiz:execute("DELETE_FILE $(tmp)")
end

function MoveFile(fn, fn_new)
    os.rename(fn, fn_new)
    --  analiz:set("tmp",fn)
    --  analiz:execute("DELETE_FILE $(tmp)")
end

local function LoadFromFile(fn)
    ss.l("LoadFromFile.start")
    local body = load_from_file_(fn)
    if body == nil then return nil end
    local mem = ss.CreateMemItem(10000)
    mem:resize(body:len())
    mem:set_string(body)
    local res = mem:read_obj()
    mem:destroy()

    -- check meta.prop
    if res.meta == nil then
        ss.l("not found meta.return nil ")
        return nil
    end -- old version
    if res.meta.nc_schema ~= global_oracle_setting.nc_schema then
        ss.l("change nc_schema.  return nil ")
        return nil
    end -- change oracle chema
    if res.meta.list_id ~= GetCurrentListID({pwd_plib = "PLIB"}) then
        ss.l("change list_id.  return nil ")
        return nil
    end -- change version 
    ss.l("LoadFromFile.return value")
    return res
end

local function SafeToFile(rec, fn)
    ss.l("load_fa_schema_params.save to file.start")
    local mem = ss.CreateMemItem(10000)
    mem:write_obj(rec)
    --  local body = mem:sub(0,mem:get_size()-1)
    local body = mem:sub(0, mem:get_point())
    mem:destroy()
    --   ss.l(debug.traceback())	
    local uname = fn .. ss.b("_$(GUID_FOR_LOG)")
    save_to_file_(uname, body)
    ss.l("load_fa_schema_params.save to file:" .. fn)
    DeleteFile(fn)
    fileserv:CopyFile(uname, fn)
    DeleteFile(uname)

end

local function LoadFromDb(fn)
    ss.l("load_fa_schema_params.LoadFromDb.start")
    local prop, emessage
    for i = 1, 10 do
        prop, emessage = loadImpl_()
        if emessage == "" then break end
        ss.e("sleep sec 30")
    end
    if emessage ~= "" then
        ss.l("sleep 15 sec and restart")
        ss.e("sleep sec 15")
        ss.e("abort 1")
    end
    ss.l("load_fa_schema_params.LoadFromDb.end")
    -- add meta prop
    prop.meta = {}
    prop.meta.update_dt = tick.now()
    prop.meta.nc_schema = global_oracle_setting.nc_schema
    prop.meta.list_id = GetCurrentListID({pwd_plib = "PLIB"})
    prop.meta.writer = ss.b("$(service_family)_$(UNIQUE_IDENTIFIER)")
    prop.meta.dt = ss.b("$(now)")
    SafeToFile(prop, fn)
    return prop
end

-- ----------------------------------------------------------------------------------------
local point0 = os.time() - getThreshold_(THRESHOLD_DT)

local function get_fa_schema_params_cache()

    local cached_fn = GetRootTempDir() .. "\\lex\\FA_SCHEMA_PARAMS.bin"
    return cached_fn
end

function clean_fa_schema_params_cache()
    ss.l("clean_fa_schema_params_cache")
    local cached_fn = get_fa_schema_params_cache()
    DeleteFile(cached_fn)
end

function load_fa_schema_paramsImpl()
    ss.l("load_fa_schema_paramsImpl.start")
    ss.s("tmp", GetRootTempDir())
    ss.e("FORCEDIRECTORIES $(tmp)")
    local cached_fn = get_fa_schema_params_cache()

    local load_from_db = true
    if fileserv:FileExists(cached_fn) then
        ss.l("load_fa_schema_paramsImpl.file found")
        local last_update = get_mod_dt_(cached_fn)
        if last_update.modification > point0 then load_from_db = false end
        ss.l("load_fa_schema_paramsImpl.dt valid")
        load_from_db = false
    end

    local res
    if load_from_db then
        res = LoadFromDb(cached_fn)
    else
        local isok
        res = LoadFromFile(cached_fn)
        if res == nil then res = LoadFromDb(cached_fn) end
    end
    return res
end

-- ----------------------------------------------------------------------------------------
local prop = load_fa_schema_paramsImpl()
global_oracle_setting.FA_SCHEMA_PARAMS = prop
ss.l("global_oracle_setting.FA_SCHEMA_PARAMS:")
ss.tprint(global_oracle_setting.FA_SCHEMA_PARAMS)

local function fix_(cur_name, internal_name)
    local name = prop[cur_name]
    if name ~= "" and name ~= nil then
        local old = global_oracle_setting.internal[internal_name]
        name = ss.ReplaceValue(name, "queue:", "")
        ss.l("fix name:" .. internal_name .. ": old value:" ..
                 ss.def(old, "<nil>") .. ".new value=" .. name)
        global_oracle_setting.internal[internal_name] = name
    end
end
do

    fix_("KUNDENSTAMM_DELTA", "input_queue_kundenstammDelta")

    fix_("CHECKPAYMENT_WORDCHECK", "input_queue_worldcheck_checkpayment")
    fix_("KUNDENSTAMM_WORDCHECK", "input_queue_worldcheck_kundenstamm")
    -- input_queue_factiva_kundenstammDelta

    fix_("KUNDENSTAMM_FACTIVA", "input_queue_factiva_kundenstamm")
    fix_("CHECKPAYMENT_FACTIVA", "input_queue_factiva_payment")
end
ss.l("global_oracle_setting.internal:")
ss.tprint(global_oracle_setting.internal)


