-- import_export_4d.lua

local util = require "util"
local exp = require "export"
local lemon = require "custom/lemonsoft/lemon"
local itella = require "custom/norex/itella"
local bys = require "custom/bysoft/bysoft"
local atenoExcel = require "custom/ateno/excel_to_sales_order"
local json = require "json"
local dschema = require "db/db_schema"
local fn = require "fn"
local dt = require "dt"
local peg = require "peg"
local query = require "query"
local l = require "lang".l
local plg = require "plugin_4d"
local dprf = require "db/db_preference"

local allowed4DFunctionCall = dprf.prf("system/4d.json").allowed_4d_function_call
-- local json = require "json"

--local ffi = require "mffi"
--ffi.setOption({trace_all = true})


local function export(param)
	local paramTbl = util.parameterToTable(param)
	return exp.export(paramTbl)
end

local function exportLemonInvoice(param)
	local paramTbl = util.parameterToTable(param)
	return lemon.exportInvoice(paramTbl)
end

local function importItella(param)
	local paramTbl = util.parameterToTable(param)
	return itella.import(paramTbl)
end

local function exportItella(param)
	local paramTbl = util.parameterToTable(param)
	return itella.export(paramTbl)
end

local function bysoft(param)
	return bys.sendAndReceive(param)
end

local function excelToSalesOrderAteno(param)
	return atenoExcel.excelToSalesOrderAteno(param)
end

local function tabDefinition(param)
	-- {table = "ordr", record_type = "sales", tab_name = "Avoimet BW,Daewoo", query_name = "manager/order/order_row/sales/record_id"}
	if param == nil then
		return {error = util.parameterError("param")}
	elseif param.table == nil then
		return {error = util.parameterError("table")}
	elseif param.tab_name == nil then
		return {error = util.parameterError("tab_name")}
	end
	param.table_local = param.table
	param.table = param.table_prefix or dschema.externalPrefix(param.table, "4d", param.record_type) -- table prefix to external
	param.tab_query = param.tab_query or ""
	plg.callMethodNoReturn("_lx_TAB",json.toJson(param))
	local ret = plg.getStringVariable("_lx_tReturnJson")
	if ret == "" then
		return {error = l("tab '%s/%s' definition is empty", param.table,param.tab_name)}
	end
	local retTbl = util.parameterToTable(ret)
	-- util.printTable(retTbl, "tabToFile/ret")
	if retTbl == nil then
		return {error = l("tab '%s/%s' definition is empty, error: '%s'", param.table, param.tab_name, tostring(retTbl.error))}
	elseif retTbl.columns == nil then -- 4D uses columns, not column
		if retTbl.record_id_count then
			return retTbl
		end
		return {error = l("tab '%s/%s', error: '%s'", tostring(param.table), tostring(param.tab_name), tostring(retTbl.error))}
	end
	return retTbl
end

local function tabToFile(param)
	local retTbl = tabDefinition(param)
	if retTbl.error then
		return retTbl.error
	end
	local fieldArr = fn.iter(retTbl.columns):map(function(rec)
		return rec.field
		--[[
		return dschema.localName(rec.field, "4d", param.record_type)
		--]]
	end):totable()
	-- util.printTable(fieldArr, "tabToFile/fieldArr")

	local queryParam = param
	queryParam.record_id = retTbl.record_id
	queryParam.field = fieldArr
	local tabData, err = query.queryJson(param.query_name, queryParam)
	if err or (tabData and tabData.info and tabData.info.error) then
		return {error = err or tabData.info.error}
	end
	if tabData and tabData.data then
		return {columns = retTbl.columns, data = tabData.data}
	end
	return {error = l("'%s/%s'-tab has no data", param.table, param.tab_name)}
end

local function call4dFunction(param_)
	local param = util.parameterToTable(param_)
	-- util.printTable(param, "call4dFunction")
	if param == nil or param.call == nil then
		return {error = util.parameterError("call")}
	end
	if param.call == "echo" then
		return {data = "echo: "..param.parameter}
	elseif param.call == "tabDefinition" then
		local ret = tabDefinition(param.parameter) -- execute.runFunction(run, retData)
		--[[ if type(ret) == "table" and ret.error then
			print(ret.error)
		end ]]
		return ret
	elseif param.call == "tabToFile" then
		local ret = tabToFile(param.parameter) -- execute.runFunction(run, retData)
		--[[ if type(ret) == "table" and ret.error then
			print(ret.error)
		end ]]
		return ret
	elseif allowed4DFunctionCall[param.call] then
		if allowed4DFunctionCall[param.call]["return"] == "string" then --  == "_lx_prf_BlobToJson"
			local ret = plg.callMethodReturnString(param.call, param.parameter)
			return {string = ret}
		elseif allowed4DFunctionCall[param.call]["return"] == "long" then
			local ret = plg.callMethodReturnLong(param.call, param.parameter)
			return {long = ret}
		elseif allowed4DFunctionCall[param.call]["return"] == "" then --  == _prf_TAB_TO_JSON, _prf_ALP_TO_JSON
			local ret = plg.callMethodNoReturn(param.call, param.parameter)
			return {}
		end
	end
	return {error = "unknown call4dFunction call", param = param}
end

return {
	export = export,
	exportLemonInvoice = exportLemonInvoice,
	importItella = importItella,
	exportItella = exportItella,
	bysoft = bysoft,
	excelToSalesOrderAteno = excelToSalesOrderAteno,
	tabDefinition = tabDefinition,
	tabToFile = tabToFile,
	call4dFunction = call4dFunction,
}
--if util.fromZbs() then
	--local param

	-- ******************
	-- test: exportInvoiceLemon
	--[[
	param = [-[
		{
		"record_id":["20150608.120814.0l009.in_  zzy0d0509942557e05"],
		"table":"in",
		"user":"MG_AK"
		}
	]-]
	local ret = exportInvoiceLemon(param)
	]]


	-- ******************
	-- test: importItella, exportItella
	--[[
	if true then
		param =[-[
			{
			"record_id":[
			"20150226.102943.8w02i.so_  o11a001f5bceeff003",
			"20150119.095811.r301w.so_  o11a00224124860706"
			],
			"table":"so"
			}
		]-]
	elseif false then
		param =[-[
			{
			"record_id":[
			"20141229.155015.0v001.po_  o11a00224124860709",
			"20141222.165245.o3004.po_  o11a3c0754650f0e03"
			],
			"table":"po"
			}
		]-]
	else
		param =[-[
			{
			"record_id":[
			"20150107.103532.oi004.pr_  o11a001f5bceeff003"
			],
			"table":"pr"
			}
		]-]
	end
	local ret = exportItella(param)
	]]


	-- ******************
	-- test: bysoft
	--[[
		param = {"08069/01", "02061/02"}
	]]
--end
