ivr_api = freeswitch.API()
cjson = require "cjson"
local company_code = session:getVariable("lcc_company_code")
local dsntvsco = string.format(session:getVariable("odbc_template") or "", "tvsco8000_" .. company_code)
local dsntvs = freeswitch.getGlobalVariable("sys_odbc_dsn")

function zstr(str)
	if str == nil or str == "" then
		return true
	else 
		return false
	end
end

function getdsntvs()
    return dsntvs
end

function getdsntvsco()
    return dsntvsco
end
function get_dbh(dsn)
        local dbh = freeswitch.Dbh(dsn)
        if dbh:connected() then
                return dbh
        else
                return nil
        end
end


function df_str(str)
	if zstr(str) then
		return ""
	else 
		return str
	end
end

function strsplit(inputstr, sep)
	if sep == nil then
		sep = "%s"
	end
	local t={} ; i=1
	for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
		t[i] = str
		i = i + 1
	end
	return t
end

function check_date_time(date_time)
	local pass = 1
	local list=strsplit(date_time,"~");
	if table.getn(list) == 2 then
		local s_t = strsplit(list[1],"-")
		if table.getn(s_t) == 3 then
			local t1 = tonumber(s_t[1])
			local year = tonumber(os.date("%Y"))
			if t1 > year then
				return 0
			elseif t1 == year then
				local t2 = tonumber(s_t[2])
				local month = tonumber(os.date("%m"))
				if t2 > month then
					return 0
				elseif t2 == month then
					if tonumber(s_t[3]) > tonumber(os.date("%d")) then return 0 end
				end
			end
		end
		local e_t = strsplit(list[2],"-")
		if table.getn(e_t) == 3 then
			local t1 = tonumber(e_t[1])
			local year = tonumber(os.date("%Y"))
			if t1 < year then
				return 0
			elseif t1 == year then
				local t2 = tonumber(e_t[2])
				local month = tonumber(os.date("%m"))
				if t2 < month then
					return 0
				elseif t2 == month then
					if tonumber(e_t[3]) < tonumber(os.date("%d")) then return 0 end
				end
			end
		end
	end
	return pass
end

function check_mday(mday)
	local pass = 0
	local list=strsplit(mday,",");
	for k,v in ipairs(list) do
		if tonumber(v)== tonumber(os.date("%d")) then return 1 end
	end
	return pass
end

function check_wday(wday)
	local pass = 0
	local list=strsplit(wday,",");
	for k,v in ipairs(list) do
		local wd = tonumber(v)
		if wd == 7 then 
			if tonumber(os.date("%w")) == 0 then return 1 end
		elseif wd == tonumber(os.date("%w")) then 
			return 1 
		end
	end
	return pass
end

function check_time_of_day(time_of_day)
	local pass = 1
	local list=strsplit(time_of_day,"-");
	if table.getn(list) == 2 then
		local s_t = strsplit(list[1],":")
		if table.getn(s_t) == 2 then
			local t1 = tonumber(s_t[1])
			local hour = tonumber(os.date("%H"))
			if t1 > hour then
				return 0
			elseif t1 == hour then
				if tonumber(s_t[2]) > tonumber(os.date("%M")) then return 0 end
			end
		end
		local e_t = strsplit(list[2],":")
		if table.getn(e_t) == 2 then
			local t1 = tonumber(e_t[1])
			local hour = tonumber(os.date("%H"))
			if t1 < hour then
				return 0
			elseif t1 == hour then
				if tonumber(e_t[2]) < tonumber(os.date("%M")) then return 0 end
			end
		end
	end
	return pass
end

function checktime(date_time,mday,wday,time_of_day)
	local pass = 1
	if not zstr(date_time) then
		pass = check_date_time(date_time)
		if pass == 0 then return 0 end
	end
	if not zstr(mday) then
		pass = check_mday(mday)
		if pass == 0 then return 0 end
	end
	if not zstr(wday) then
		pass = check_wday(wday)
		if pass == 0 then return 0 end
	end
	if not zstr(time_of_day) then
		pass = check_time_of_day(time_of_day)
	end
	return pass
end

function ivr_dialext(des)
	if not session:ready() then return end
	if des == nil or des =="" then return end
	-- ivr_api:execute("cr_ivr_dialext_cmd", des)
	local new_des = session:getVariable(des)
	if new_des == nil or new_des == "" then
		-- 呼叫默认的
		session:execute("bridge",des.." 1 [callin_process_mode=callin_toivr,b_calltype=1]")
	else
		session:execute("bridge",new_des.." 1 [callin_process_mode=callin_toivr,b_calltype=1]")
    end
end

function ivr_dialext(agentid, ringtimeout)
	if not session:ready() then return end
	if agentid == nil or agentid =="" then return end
        local uuid = session:getVariable("uuid")
	local caller_number = session:getVariable("caller_id_number");
        local reqqueuedata =
        {
                company_code = company_code,
                caller_number = caller_number,
                timeout = ringtimeout,
                uuid = uuid,
		agent_id = agentid,
                type = 2
        };
        session:setVariable("lcc_call2java_jparam", cjson.encode(reqqueuedata))
        local reqqueuedataStr = session:getVariable("lcc_call2java_jparam");
        if reqqueuedataStr ~=  nil then
                freeswitch.consoleLog("INFO", "reqqueuedataStr:"..reqqueuedataStr);
        end

        --session:execute("lcc_call_queue_start",ringtimeout)
	session:execute("lcc_call2java_action")
end

function ivr_dialoutline(des)
	if not session:ready() then return end
	if des == nil or des =="" then return end
	local new_des = session:getVariable(des)
	if new_des == nil or new_des == "" then
		local flag = string.sub(des, 1, 6)
		if flag == "000001" then
			local ff = string.sub(des, 7)
			local company_code = session:getVariable("company_code")
			session:execute("lua","src/"..company_code.."_"..ff..".lua")
		else
			-- 呼叫默认的
			session:execute("calloutroute",des.." [origination_caller_id_number="..session:getVariable("caller_id_number")..",callin_process_mode=callin_toivr]")
		end
	else
		session:execute("calloutroute",new_des.." [origination_caller_id_number="..session:getVariable("caller_id_number")..",callin_process_mode=callin_toivr]")
    end
end

function ivr_dialoutline(outline, ringtimeout)
        if not session:ready() then return end
        if outline == nil or outline =="" then return end
        local uuid = session:getVariable("uuid")
        local caller_number = session:getVariable("caller_id_number");
        local reqqueuedata =
        {       
                company_code = company_code,
                caller_number = caller_number,
                timeout = ringtimeout,
                uuid = uuid,
		outline_number = outline,
                type = 3
        };
        session:setVariable("lcc_call2java_jparam", cjson.encode(reqqueuedata))
        local reqqueuedataStr = session:getVariable("lcc_call2java_jparam");
        if reqqueuedataStr ~=  nil then
                freeswitch.consoleLog("INFO", "reqqueuedataStr:"..reqqueuedataStr);
        end

        --session:execute("lcc_call_queue_start",ringtimeout)
	session:execute("lcc_call2java_action")
end

function ivr_playAndGetDigits(min_digits,max_digits,max_attempts,timeout,prompt_audio_files,error_audio_files)
	if not session:ready() then return end
	if min_digits<1 or min_digits>100 then
		min_digits = 1
	end
	if max_digits<1 or max_digits>100 then
		max_digits = 100
	end
	if min_digits>max_digits then
		min_digits = max_digits
	end
	local endinput = "#"
	if min_digits==max_digits then
		endinput = ""
	end
	if max_attempts<1 or max_attempts>100 then
		max_attempts = 100
	end
	if timeout<1 or timeout>60000 then
		timeout = 60000
	end
	local digit_regex = "^.{"..min_digits..","..max_digits.."}$"
	--freeswitch.consoleLog("info",digit_regex)
	--session:execute("spandsp_start_dtmf")
	session:execute("playback","/usr/local/freeswitch/sounds/space.wav");
	local digits_res = session:playAndGetDigits(
				min_digits,
				max_digits,
				max_attempts,
				timeout,
				endinput,
				prompt_audio_files,
				--freeswitch.getGlobalVariable("vc_digit_failed_path"),
				"",
				digit_regex)
	--session:execute("spandsp_stop_dtmf")
	return digits_res
end

function ivr_playAndGetDigits_ex(min_digits,max_digits,max_attempts,timeout,prompt_audio_files,error_audio_files,n_id,n_name, dtmfprefix)
	if not session:ready() then return end
	if min_digits<1 or min_digits>100 then
		min_digits = 1
	end
	if max_digits<1 or max_digits>100 then
		max_digits = 100
	end
	if min_digits>max_digits then
		min_digits = max_digits
	end
	local endinput = "#"
	if min_digits==max_digits then
		endinput = ""
	end
	if max_attempts<1 or max_attempts>100 then
		max_attempts = 100
	end
	if timeout<1 or timeout>60000 then
		timeout = 60000
	end
	local digit_regex = "^.{"..min_digits..","..max_digits.."}$"
	--freeswitch.consoleLog("info",digit_regex)
	-- session:execute("spandsp_start_dtmf")
	session:execute("playback","/usr/local/freeswitch/sounds/space.wav");
	local digits_res = session:playAndGetDigits(
				min_digits,
				max_digits,
				max_attempts,
				timeout,
				endinput,
				prompt_audio_files,
				--freeswitch.getGlobalVariable("vc_digit_failed_path"),
				"",
				digit_regex)
	-- session:execute("spandsp_stop_dtmf")

	local key_trace = session:getVariable("userkey_f10")
    	if key_trace == nil or key_trace == "" then
		if dtmfprefix == nil or dtmfprefix == "" then
    			session:setVariable("userkey_f10", n_id.."（"..n_name.."）_"..os.date("%Y%m%d%H%M%S",os.time()).."："..digits_res.."；")
		else
			session:setVariable("userkey_f10", n_id.."（"..n_name.."）_"..os.date("%Y%m%d%H%M%S",os.time()).."："..digits_res.."|"..dtmfprefix.."；")
		end
	else
		if dtmfprefix == nil or dtmfprefix == "" then
			session:setVariable("userkey_f10", key_trace.."\n"..n_id.."（"..n_name.."）_"..os.date("%Y%m%d%H%M%S",os.time()).."："..digits_res.."；")
		else
			session:setVariable("userkey_f10", key_trace.."\n"..n_id.."（"..n_name.."）_"..os.date("%Y%m%d%H%M%S",os.time()).."："..digits_res.."|"..dtmfprefix.."；")
		end
    	end

	return digits_res
end

function ivr_runcc(queuename,queueouttime,companycode,real_caller)
	if not session:ready() then return end
	-- freeswitch.consoleLog("info","ivr_runcc...................start\n")
    local runcc_times = session:getVariable("runcc_times")
    if runcc_times == nil then
    	runcc_times = os.time()
    	session:setVariable("runcc_times", runcc_times)
    end
    local cc_busy_no = session:getVariable("cc_busy_no")
    if cc_busy_no == nil then
        cc_busy_no = 1
    else
	cc_busy_no = cc_busy_no + 1
    end
    session:setVariable("cc_busy_no", cc_busy_no)
    session:setVariable("cc_queue_hangup", "1")

    -- local uuid = session:get_uuid()
    -- if uuid ~= nil and uuid ~= "" then
    -- 	ivr_api:execute("cr_hiredis_cmd", "\"lpush\",\""..queuename..":calls\",\""..uuid.."\"")
    -- 	ivr_api:execute("cr_hiredis_cmd", "\"expire\",\""..queuename..":calls\",\"120\"")
    -- 	-- ivr_api:execute("cr_hiredis_cmd", "ivrchans lpush "..queuename..":calls "..uuid)
    --  	-- ivr_api:execute("cr_hiredis_cmd", "ivrchans expire "..queuename..":calls 120")
    -- end
	
	session:setVariable("effective_caller_id_name", "Queue Caller")
        local caller_number = session:getVariable("caller_id_number");
        local uuid = session:getVariable("uuid")
	local reqqueuedata =
	{
		skill_id = queuename,
		company_code = companycode,
		caller_number = real_caller,
                timeout = queueouttime,
                current_times = cc_busy_no,
                uuid = uuid,
                type = 1
	};
        session:setVariable("lcc_call2java_jparam", cjson.encode(reqqueuedata))
        local reqqueuedataStr = session:getVariable("lcc_call2java_jparam");
        if reqqueuedataStr ~=  nil then
        	freeswitch.consoleLog("INFO", "reqqueuedataStr:"..reqqueuedataStr);
        end

	--session:execute("limit","hash inbound ${destination_number} 30/1 !NORMAL_CIRCUIT_CONGESTION")
	-- session:execute("set","hangup_after_bridge=true")
	--session:execute("lcc_call_queue_start",queuename.." "..companycode.." "..real_caller.." "..queueouttime.." "..cc_busy_no.." 1")
	session:execute("lcc_call2java_action")
	if not session:ready() then return end
	session:setVariable("cc_queue_hangup", "0")
	-- 如果b路应答过，就停止累计计算队列排队时长
	local b_answer_stamp = session:getVariable("b_answer_stamp")
	if b_answer_stamp == nil then
		local cc_ringbacktimes = os.time() - runcc_times
		session:setVariable("cc_ringbacktimes", cc_ringbacktimes)
	else
		local cc_ringbacktimes = session:getVariable("cc_ringbacktimes")
		if cc_ringbacktimes == nil then
			local cc_ringbacktimes = os.time() - runcc_times
			session:setVariable("cc_ringbacktimes", cc_ringbacktimes)
		end
	end
	
	-- freeswitch.consoleLog("info","ivr_runcc...................leave"..cc_ringbacktimes.."\n")

	-- if uuid ~= nil and uuid ~= "" then
	-- 	ivr_api:execute("cr_hiredis_cmd", "\"lrem\",\""..queuename..":calls\",\"0\",\""..uuid.."\"")
	-- 	-- ivr_api:execute("cr_hiredis_cmd", "ivrchans lrem "..queuename..":calls 0 "..uuid)
	-- end
end

function httpgetrequest(request_para)
	if not session:ready() then return end
	session:setVariable("curl_timeout", "10")
	session:execute("curl", request_para)
	local curl_response_code = session:getVariable("curl_response_code")
	if curl_response_code == "200" then
		return session:getVariable("curl_response_data")	
	else
		return "{\"result\":\"yes\"}"
	end
end

function codificaParametros(paramsT,sep)
    function escape (s)
        s = string.gsub(
            s,
            '([\r\n"#%%&+:;<=>?@^`{|}%\\%[%]%(%)$!~,/\'])',
            function (c)
                return '%'..string.format("%X", string.byte(c))
            end
        )
        s = string.gsub(s, "%s", "+")
        return s
    end
    function encode (t)
      local s = ""
      for k , v in pairs(t) do
        s = s .. "&" .. escape(k) .. "=" .. escape(v)
      end
      return string.sub(s, 2)
    end
    if type(paramsT) == 'table' then
        return encode(paramsT)
    else
        --local tmp = Utils:commaText(paramsT, '&');
		local tmp = strsplit(paramsT, sep);
        local myParamsT = {};
        for k, v in pairs(tmp) do
            local pos = 0
            pos = string.find(v, '=')
            if not pos then return '' end
            myParamsT[string.sub(v, 1, pos-1 )] = string.sub(v, pos+1 )
        end
        return encode(myParamsT)
    end
end

function ivr_httpapi(url,method,paras)
	if not session:ready() then return end
	if not zstr(url) then
		local t_paras = strsplit(paras,"|")
		local tab = {}
		for k, v in pairs(t_paras) do
			local val = session:getVariable(v)
			if not zstr(val) then 
				tab[v] = val
			end
		end
		local curl_response_data = nil
		if method == "POST" then
			curl_response_data = httpgetrequest(url.." post "..codificaParametros(tab,nil))
		else
			curl_response_data = httpgetrequest(url.."?"..codificaParametros(tab,nil))
		end
		session:consoleLog("info", "Got curl_response_data: ".. curl_response_data .."\n")		
		if curl_response_data ~= nil then
			local j_res = cjson.decode(curl_response_data)
			if j_res ~=nil and type(j_res) == "table" then
				for k, v in pairs(j_res) do
					if v ~=nil  then --and not type(v) == "userdata"
						session:consoleLog("info", type(v).." set : "..k.."="..v.."\n")
						session:execute("set",k.."="..v)
					end
				end
			end
		end
	end
end

function ivr_vc_recorder_loop(torecordputkey)
	if not session:ready() then return end
	if torecordputkey == "2" then
		session:execute("playback",df_str(session:getVariable("leavemsg_filepath")))
		session:setVariable("torecordputkey","")
		session:execute("play_and_get_digits","1 1 1 5000 # "..df_str(freeswitch.getGlobalVariable("vc_df_vm_review")).." 1 "..
					df_str(freeswitch.getGlobalVariable("vc_digit_failed_path")).." torecordputkey \\d+")
		ivr_vc_recorder_loop(session:getVariable("torecordputkey"))
	elseif torecordputkey == "3" then
		session:execute("playback",df_str(freeswitch.getGlobalVariable("vc_df_vm_beep")))
		local leavemsg_filepath = session:getVariable("leavemsg_filepath")
		session:execute("record_session",leavemsg_filepath)
		session:execute("conference","vm_"..session:getVariable("short_channel_name").."@for_vm++flags{endconf|moderator|nomoh}")
		session:execute("stop_record_session",leavemsg_filepath)
		session:setVariable("torecordputkey","")
		session:execute("play_and_get_digits","1 1 1 5000 # "..df_str(freeswitch.getGlobalVariable("vc_df_vm_review")).." 1 "..
					df_str(freeswitch.getGlobalVariable("vc_digit_failed_path")).." torecordputkey \\d+")
		ivr_vc_recorder_loop(session:getVariable("torecordputkey"))
	else
		session:execute("playback",df_str(freeswitch.getGlobalVariable("vc_df_vm_msgsaved")))
	end
end

function ivr_vc_recorder()
	if 1 then return end
	if not session:ready() then return end
	local record_path = freeswitch.getGlobalVariable("record_dir").."/vm/"..company_code.."/"..ivr_api:execute("strftime", "%Y%m%d").."/"..ivr_api:execute("strftime", "%Y%m%d%H%M%S").."_"..session:getVariable("destination_number").."_"..session:getVariable("caller_id_number")
	local default_rcd_mime = freeswitch.getGlobalVariable("default_rcd_mime")
	if zstr(default_rcd_mime) then default_rcd_mime = "wav" end
	local short_channel_name = session:getVariable("short_channel_name")
	local f_path = record_path.."."..default_rcd_mime
	-- local df_vm_intro = freeswitch.getGlobalVariable("vc_df_vm_intro")
	local df_vm_review = freeswitch.getGlobalVariable("vc_df_vm_review")
	local df_vm_beep = freeswitch.getGlobalVariable("vc_df_vm_beep")
	session:execute("sleep",500)
	if not zstr(df_vm_intro) then session:execute("playback",df_vm_intro) end
	session:setVariable("leavemsg_filepath",f_path)
	session:execute("sleep",500)
	if not zstr(df_vm_beep) then session:execute("playback",df_vm_beep) end
	local leavemsg_filepath = session:getVariable("leavemsg_filepath") 
        -- add start by chenj 
        session:execute("set", "record_sample_rate=8000");
        session:execute("set", "RECORD_STEREO=false");
        -- add end
	session:execute("record_session",leavemsg_filepath)
	if zstr(short_channel_name) then short_channel_name = session:getVariable("caller_id_number") end
	session:execute("sched_hangup","+"..session:getVariable("leavemsg_max_duration").." alloted_timeout")
	session:setVariable("leavemsg_start",ivr_api:execute("strepoch", ""))
	session:execute("conference","vm_"..df_str(session:getVariable("short_channel_name")).."@for_vm++flags{endconf|moderator|nomoh}")
	session:execute("stop_record_session",leavemsg_filepath)
	-- session:execute("cus_play_and_get_digits","1 1 1 10000 # "..df_str(df_vm_review).." 1 silence_stream://250 torecordputkey \\d+")
	-- ivr_vc_recorder_loop(session:getVariable("torecordputkey"))
end

function ivr_vc_recorder(timeout,endkey,startvidio)
        if not session:ready() then return end
        local uuid = session:getVariable("uuid")
        local caller_number = session:getVariable("caller_id_number");
        local reqqueuedata =
        {
                company_code = company_code,
                caller_number = caller_number,
                timeout = timeout,
                uuid = uuid,
                dtmf = endkey,
                message_start_record_tone = startvidio,
                type = 4
        };
        session:setVariable("lcc_call2java_jparam", cjson.encode(reqqueuedata))
        local reqqueuedataStr = session:getVariable("lcc_call2java_jparam");
        if reqqueuedataStr ~=  nil then
                freeswitch.consoleLog("INFO", "reqqueuedataStr:"..reqqueuedataStr);
        end

        --session:execute("lcc_call_queue_start",timeout)
	session:execute("lcc_call2java_action")
end
