----------------------------------
-- 屏蔽词过滤
-- filter 			聊天信息过滤
-- filterName 		角色名过滤
----------------------------------
local Dict = require("common.Dict")
local Dict2 = require("common.Dict2")
local Config = require("Config")
local CommonDefine = require("common.CommonDefine")

local function isAllowSpaceInName()
	return table.find(Config.SVR_CHANEL or {}, CommonDefine.CHANNEL_TAG_VN) ~= nil
end

-- 初始
local dict_maxx = 0
for k in pairs(Dict) do
	if type(k) == "string" then
		local klen = #k
		if klen < 1 then
			assert()
		end
		if dict_maxx < klen then
			dict_maxx = klen
		end
	end
end

local DictBol = { 
["["] = true, 
["]"]= true,
["\\"]= true,
["\""]= true,
["'"]= true,
["/"]= true,
[" "]= true,
["　"]= true,
[" "]= true,
["@"]= true,
["&"]= true,
["`"]= true,
["~"]= true,
["$"]= true,
["%"]= true,
["^"]= true,
["*"]= true,
["("]= true,
[")"]= true,
["-"]= true,
["{"]= true,
["}"]= true,
[":"]= true,
[";"]= true,
["|"]= true,
["<"]= true,
[">"]= true,
["?"]= true,
["."]= true,
["="]= true}

local tb_bol = {}
function filter_bol(a, dict, dictNum)
    dict = dict or DictBol
	local tblen = len or 0
	local i = 1
	local alen = #a
	local ac
	while i <= alen do
		local j = math.min(alen, i + dict_maxx - 1)
		while i <= j do
			if dict[string.sub(a, i, j)] == true then
				break
			end

            if dictNum ~= nil and dictNum == true then
               if dict.filterNum[string.sub(a, i, j)] ~= nil then
                  break
               end
            end
           
			j = j - 1
		end
		if j < i then
			tblen = tblen + 1
			tb_bol[tblen] = string.sub(a, i, i)
			i = i + 1
		else
			ac = true
			tblen = tblen + 1
			tb_bol[tblen] = ""
			i = j + 1
		end
	end
	if not ac then
		return a
	end
	local b = table.concat(tb_bol, nil, 1, tblen)
	return b
end

local tb_dest = {}
function filter_dest(a, dict, dictNum)
	dict = dict or Dict
	local tblen = len or 0
	local i = 1
	local alen = #a
	local ac
	while i <= alen do
		local j = math.min(alen, i + dict_maxx - 1)
		while i <= j do
			if dict[string.sub(a, i, j)] == true then
				break
			end

            if dictNum ~= nil and dictNum == true then
               if dict.filterNum[string.sub(a, i, j)] ~= nil then
                  break
               end
            end
           
			j = j - 1
		end
		if j < i then
			tblen = tblen + 1
			tb_dest[tblen] = string.sub(a, i, i)
			i = i + 1
		else
			ac = true
			tblen = tblen + 1
			tb_dest[tblen] = "*"
			i = j + 1
		end
	end
	if not ac then
		return a
	end
	local b = table.concat(tb_dest, nil, 1, tblen)
	return b
end


function filter(a, dict, dictNum)
	--a = filter_bol(a, dict, dictNum)
    a = filter_dest(a, dict, dictNum)
    a = filter_dest(a, Dict2, dictNum)
    return a
end

local fk_letter = {
"[","]","\\","\"","'","/"," ","　"," ","@","&","`","~","$","%","^","*","(",")","-","{","}",":",";","|","<",">","?",".","="}
function filterName(name)
	local allowSpace = isAllowSpaceInName()
	local ret = filter_spec_chars(name, allowSpace)
	if ret ~= name then
		return
	end

	for _, v in ipairs(fk_letter) do
		if not (allowSpace and v == " ") and string.find(name, v, 1, true) then
			return
		end
	end
	return filter(name)
end

function filter_spec_chars(s, allowSpace)
    local ss = {}
    local k = 1
    while true do
        if k > #s then break end
        local c = string.byte(s,k)
        if not c then break end
        if c<192 then
            if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) or (allowSpace and c == 32) then
                table.insert(ss, string.char(c))
            end
            k = k + 1
        elseif c<224 then
			local c1 = string.byte(s,k+1)
			if c1 then
				table.insert(ss, string.char(c, c1))
			end
            k = k + 2
        elseif c<240 then
			local c1 = string.byte(s,k+1)
			local c2 = string.byte(s,k+2)
			if c1 and c2 then
				local unic = (c % 0xe0) * 2 ^ 12 + (c1 % 0x80) * 2 ^ 6 + (c2 % 0x80)
      			if unic >= 0x4e00 and unic <= 0x9FA5 then
					table.insert(ss, string.char(c, c1, c2))
				end
			end
            k = k + 3
        elseif c<248 then
			local c1 = string.byte(s,k+1)
			local c2 = string.byte(s,k+2)
			local c3 = string.byte(s,k+3)
			if c1 and c2 and c3 then
				table.insert(ss, string.char(c, c1, c2, c3))
			end
            k = k + 4
        elseif c<252 then
			local c1 = string.byte(s,k+1)
			local c2 = string.byte(s,k+2)
			local c3 = string.byte(s,k+3)
			local c4 = string.byte(s,k+4)
			if c1 and c2 and c3 and c4 then
				table.insert(ss, string.char(c, c1, c2, c3, c4))
			end
            k = k + 5
        elseif c<254 then
			local c1 = string.byte(s,k+1)
			local c2 = string.byte(s,k+2)
			local c3 = string.byte(s,k+3)
			local c4 = string.byte(s,k+4)
			local c5 = string.byte(s,k+5)
			if c1 and c2 and c3 and c4 and c5 then
				table.insert(ss, string.char(c, c1, c2, c3, c4, c5))
			end
            k = k + 6
        else
			assert(nil)
        end
    end
    return table.concat(ss)
end