analiz:log("--serv.lua-")

local tick = CreateTimeServ()
local perf_sum_all = 0
local perf_count = -1
local delta_sum = 0
local finn_serv = analiz.mix.finnova.serv
local ss = analiz.libs.serv

local fgenerator = CreateGenerateThrow() -- todo
fgenerator:init("lex_w")

ss.l("load:serv.lua")
tmp_serv_task_lua = {}

local point_0=-1

function writePerfImpl(tag, t)

   if true then return end
   if point_0==-1 then return end
    analiz:log("writePerf:" .. tag .. "\t" .. t)
    local file = io.open("c:\\single_perf.log", "a")
    file:write(tag .. "\t" .. tick.to_msec(t-point_0) .. "\n")
    file:close()
end

function IsAssertTask(task)
    if task == nil then return nil end
    if task.data == nil then return nil end
    return task.data.lastname == "{C4BC6514-05DF-4C37-9ED4-78C25FAD2877}"
end

function writePerfStart(tag) 
point_0 = tick.now()
writePerfImpl(tag,point_0 ) 
end
function writePerf(tag) writePerfImpl(tag, tick.now()) end

local last_task = nil
local last_corrid = nil
local gTag = nil
local global_oserv = nil

function send_error_custom_logic_for_worker(emessage)
    if last_task == nil then return end
    local bid = last_task.data.bid
    local corrid = last_task.corrid

    local oret = {}

    oret.bid = bid
    oret.score = -1

    if emessage:len() > 50 then emessage = emessage:sub(1, 50) end
    oret.worker = gTag .. ":" .. emessage
    ss.l("error.info:" .. oret.worker)

    oret.start_dt = last_task.data.start_dt
    ss.l("send ret...")
    ss.tprint(oret)
    global_oserv.queue_out:send(oret, {correlation = last_corrid})
    writePerf("lex_full." .. gTag .. ".commit_result")

    ss.l("commit...")
    global_con:commit()
    record_status_obj:add(bid, corrid, "send to failed", oret.score)

end

-- ----------------------------------------------------------------------------
function create_engine(ora)
    ss.l("-create_engine-")
    local engine = {}
    engine.processing = {count = 0}

    engine.ora = ora

    engine.ora_serv = {}
    local oserv = engine.ora_serv

    global_oserv = oserv
    --    global_con = ora.con
    engine.queue_engine = ora.queue_engine

    ss.l("198789911")
    local queue_name = finn_serv.GetFullQName(ora:serv_loc_out())
    ss.l(queue_name)
    --   ss.a("aaa1aa")
    --  oserv.queue_out = ora:GetOutQueue(queue_name)

    ora:init_q_name()
    if ss.g("family_id") == "management" then
        oserv.queue_out = nil
    else
        oserv.queue_out = engine.queue_engine:createWriter(
                              {
                name = "final",
                mode = "writer2",
                ttype = global_oracle_setting.internal.out_type,
                queue = queue_name
            }) -- send result
    end

    -- --------------------------
    function engine:processing_task(task)
        local tag = analiz:get("UNIQUE_IDENTIFIER")
        last_task = task
        gTag = tag
        if IsHeartBeatTask(task) then
            task.heartbeat = true
            analiz:set("tmp", task.file)
            analiz:execute("LEX_PUBLISH_FINISH_TASK $(tmp) 0")
            return "0"
        end

        if IsAssertTask(task) then
            ss.l("test assert:")
            fgenerator:doit(task.data.firstname)
            ss.l("test assert:skip")
        end

        if (task.start_dt == nil) then
            analiz:log("task.start_dt is nil!!!")
            task.start_dt = tick.now()
        end
        record_status_obj:add(task.data.bid, task.corrid, "start", "")
        writePerf("lex_full." .. tag .. ".start")
        GetPerfLog("start.lex", task.start_dt)
        analiz:set("tmp", task.file)
        analiz:execute("echo task=$(tmp)")
        local start_dt = tick.now()
        analiz:execute(
            "LEX_FAST_COMPARE_ENGINE ret_code $(server_name) $(tmp) $(is_delete)");

        local ret = analiz:get("ret_code")
        local last_error = analiz:get("ResultWriter.last_error")

        if last_error == "" and ret ~= "0" then
            last_error = "ret_code:" .. ret
        end
        analiz:execute("echo ResultWriter.best.score=$(ResultWriter.best.score)")

        if (last_error ~= "") then
            analiz:log("ResultWriter.last_error=" .. last_error)
        end
        --      analiz:execute("abort 1")
        local tt = tick.now()
        --      analiz:log("task.end.lex:"..tt)
        GetPerfLog("end.lex", tt)
        writePerf("lex_full." .. tag .. ".end")
        local delta = tick.to_msec(tt - start_dt)

        local bid = ""
        if not (task.bid == nil) then bid = ",bid:" .. bid end

        analiz:set("tmp0", delta)
        analiz:set("tmp2", perf_count)
        if perf_count == -1 then
            analiz:set("tmp2", "--")
        else
            delta_sum = delta_sum + delta
            analiz:set("tmp1", "" .. delta_sum / (perf_count + 1))
        end
        analiz:set("tmp_last", "" .. delta)
        analiz:execute(
            "SHOW_TITLE $(caption_str):cur:$(tmp0):count:$(tmp2),avg:$(tmp1)" ..
                bid .. ",last:$(tmp_last)")
        analiz:execute("echo retcode=$(ret_code)")
        local msec_all = tick.to_msec(tick.now() - task.start_dt)
        perf_sum_all = perf_sum_all + msec_all
        perf_count = perf_count + 1
        analiz:log("perf_sum.all(msec):\t" .. msec_all)
        if perf_count == 0 then
            perf_sum_all = 0
        else
            analiz:log("perf_sum.all.avg(msec):\t" .. perf_sum_all / perf_count)
        end
        analiz:log("perf_count:" .. perf_count)

        engine.processing.count = engine.processing.count + 1

        -- a34 send finish_task

        ss.l("___________________________________")
        if true then
            local oserv = self.ora_serv
            local oret = {}
            oret.bid = task.data.bid
            oret.score = analiz:tonumber(analiz:get("ResultWriter.best.score"))

            if last_error == "" then
                oret.worker = tag
            else
                if last_error:len() > 50 then
                    last_error = last_error:sub(1, 50)
                end
                oret.worker = tag .. ":" .. last_error
                ss.l("error.info:" .. oret.worker)
            end
            if oserv.queue_out ~= nil then
                oret.start_dt = task.data.start_dt

                ss.l("send ret...")
                ss.tprint(oret)

                oserv.queue_out:simple_send(oret, {
                    correlation = ss.def(task.corrid, "corridZZZc")
                })
                writePerf("lex_full." .. tag .. ".commit_result")

                ss.l("commit...")
                oserv.queue_out:commit()
            end
            last_task = nil
            record_status_obj:add(task.data.bid, task.corrid, "finish",
                                  oret.score)
        end
        return ret
    end
    -- --------------------------
    return engine
end

function CheckPattern(a, b)
    local r = string.find(a, b)
    return not (r == nil)
end

-- ------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------

function create_ctx(ora)
    local t = analiz:get("type")
    analiz:log("create_ctx.type:" .. t)
    local tag = analiz:get("family_id")
    if tag == "management" then
        if t == "BATCH" then
            return create_management_batch_ctx()
        else
            return create_management_ctx(ora)
        end
    end
    return create_std_ctx(ora)
end

-- ------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------

function create_ctx2() return create_std_ctx() end
-- ------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------
function create_ctx1()

    local tag = analiz:get("work_dir")
    if CheckPattern(tag, "single") then return create_single_ctx() end

    return create_std_ctx()
end
-- ------------------------------------------------------------------------------

-- ------------------------------------------------------------------------------
function IsHeartBeatTask(task)
    local hb = task.heartbeat -- GetParamFromTask(task,"heartbeat")
    if hb == "yes" then return true end
    --      writePerf("IsHeartBeatTask.check.start")
    hb = GetParamFromTask(task, "heartbeat")
    --      writePerf("IsHeartBeatTask.check.end")
    analiz:log("isheartbeat:" .. hb)
    return hb == "yes"
end

-- ------------------------------------------------------------------------------

function CreateHeartBeatTask()
    return null
    --[[    analiz:execute("calc_param tmp $(temp)\\HeartBeat_$(GUID_FOR_LOG).task")
    analiz:execute("CREATE_OR_CLEAR_STRING_MAP HeartBeat_map")
    analiz:execute("echo LEX_CREATE_TASK $(tmp) TXT HeartBeat_map  $(template_hb_str)")
    analiz:execute("LEX_CREATE_TASK $(tmp) TXT HeartBeat_map  $(template_hb_str)")

    local task={}
    task.file = analiz:get("tmp")
    task.heartbeat="yes"
    return task
--]]
end

-- ------------------------------------------------------------------------------
function GetParamFromTask(task, name)
    -- avral fix.start
    if task == null then return "" end
    if task.type == null then return "" end
    -- avral fix.end

    if not (task.type == "file") then
        analiz:execute("sleep sec 15")
        a("failed task type:" .. task.type)
    end
    analiz:set("tmp", task.file)
    analiz:execute("LOAD_SOURCE_DATA tmp_data N $(tmp)")
    analiz:execute("CREATE_OR_CLEAR_STRING_MAP tmp_map")
    analiz:execute("STRING_MAP_LOAD_FROM_TABLE tmp_map tmp_data NAME	VALUE 0")
    local m = analiz:map_get("tmp_map")
    tmp_serv_task_lua = {}
    analiz:execute("LUA_MAP_TO_OB lua tmp_serv_task_lua tmp_map")
    task.data = ss.deepcopy(tmp_serv_task_lua)
    return m:get(name)
end
-- ------------------------------------------------------------------------------

function GetScriptTable()
    analiz:set("tmp_plib", "Sanction lists\\Std sanction list")
    analiz:execute(
        "EXTRACT_FROM_PLIB_TABLENAME tmp PLIB $(tmp_plib) $(empty) $(empty)")
    analiz:execute("echo plib table:$(tmp)")
    --   analiz:execute("abort 1")
    return analiz:get("tmp")

end
-- ------------------------------------------------------------------------------
function GetPerfLog(name, t)
    --  analiz:execute("calc_param tmp_fn $(temp)\\lex\\perf.monitoring.log")
    analiz:log("perf." .. name .. "\t" .. t)
    --  analiz:execute("ADD_TO_FILE $(tmp_fn) $(UNIQUE_IDENTIFIER)$(tab)"..name.."$(tab)"..t.."$(new_line)")
end

function CreateTickStat(name)
    local s = {count = 0, max = 0, sum = 0, last = 0}

    s.name = name

    function s:show()
        if self.count == 0 then
            ss.l("statistic:" .. self.name .. " count:0")
            return
        end
        local str1 = "statistic:" .. self.name .. "\tlast:" .. self.last ..
                         "msec"
        local str2 = "\tcount:" .. self.count .. "\tavg:" .. self.sum /
                         self.count .. " msec"
        local str3 = "\tmax:" .. self.max .. " msec"
        analiz:log(str1 .. str2 .. str3)
    end

    function s:start() self.start_time = tick.now() end

    function s:finish()
        if self.start_time == nil then
            ss.l("failed.CreateTickStat:self.start_time is null" .. self.name)
            ss.l(debug.traceback())
            self.start_time = tick.now()

        end
        local d = tick.to_msec(tick.now() - self.start_time)
        if self.count == 0 then
            self.max = d
        else
            if d > self.max then self.max = d end
        end
        self.last = d
        self.count = self.count + 1
        self.sum = self.sum + d
    end
    return s
end

function CreateOutLogger()
local out_logger = {}

function out_logger:init(is_debug_out,file_name,engine,ttype)
    self.disable_ = not (is_debug_out)
    if self.disable_ then
        ss.l("out_logger:disable")
        return
    end
    self.ttype_ = ttype
    self.file_ = ss.b(file_name)
    self.io_ = io.open(self.file_, "w+")
    self.engine_ = engine
    ss.l("out_logger:init:" .. self.file_)
    name_ = ""
    val_ = ""
    cache_ = {}
end
function out_logger:close()
    if self.io_ == nil then return end
    self.io_:close()
    self.io_ = nil
    self.cache_ = {}
end

function out_logger:begin_rec()
    if (self.disable_) then return end
    self:log(ss.b("begin:$(now)"))
    self.engine_:set_debug(self)
--    oMQ.set_debug(self)
    self.cache_ = {}
end

function out_logger:log(msg)
    if (self.disable_) then return end
    msg = ss.def(msg, "<null>")
    ss.l("out_logger:log:" .. msg)
    if self.io_ == nil then return end
    self.io_:write(msg .. "\n")
    self.io_:flush()
end

function out_logger:end_rec()
    if (self.disable_) then return end

    self.engine_:set_debug(nil)
    if self.ttype_=="bot" then 
    if self.cache_["CF_HIT_FLAG"] == nil then
        self:log("failed.CF_HIT_FLAG not found:" .. ss.toJson_sort(self.cache_))
    end
    end
    self:log("_______________________________________")
end

function out_logger:log_set(key, value, ttype)
    key = ss.def(key, "")
    value = ss.def(value, "")
    --   ss.l("out_logger:log_set:"..key..":"..value)
    if key == "STR_VALUE" then
        self.val_ = value
        return
    end
    if key == "NAME" then
        self.name_ = value
        return
    end
--[[   if ttype == "elem:set_obj" and self.name_=="F_CUSTOMER_ID" then 
      ss.l("out_logger:log_set:F_CUSTOMER_ID")
     ss.l(debug.traceback())
   end
--]]
    if ttype == "elem:set_obj" then
        self.cache_[self.name_] = self.val_
        self:log(ss.def(self.name_, "nil") .. "='" .. ss.def(self.val_, "nil").."'")
        self.name_ = ""
        self.value_ = ""
    end

end
 return out_logger
end

