
local m, s, o
local openclash = "openclash"
local NXFS = require "nixio.fs"
local SYS  = require "luci.sys"
local HTTP = require "luci.http"
local DISP = require "luci.dispatcher"
local UTIL = require "luci.util"
local fs = require "luci.openclash"
local uci = require "luci.model.uci".cursor()

m = Map(openclash,  translate("Rule Providers Append"))
m.pageaction = false
m.description=translate("Attention:")..
"<br/>"..translate("The game proxy is a test function and does not guarantee the availability of rules")..
"<br/>"..translate("Preparation steps:")..
"<br/>"..translate("1. Check the policy group and node you are going to use, Policy group type suggestion: fallback, game nodes must be support UDP and not a Vmess")..
"<br/>"..translate("2. Click the <manage third party game rules> or <manage third party rule set> button to enter the rule list and download the rules you want to use")..
"<br/>"..translate("3. On this page, set the corresponding configuration file and policy group of the rule you have downloaded, and save the settings")..
"<br/>"..
"<br/>"..translate("When setting this page, if the groups is empty, please go to the <Onekey Create> page to add")..
"<br/>"..
"<br/>"..translate("Introduction to rule set usage: https://wiki.metacubex.one/config/rule-providers/content/")

function IsRuleFile(e)
e=e or""
local e=string.lower(string.sub(e,-6,-1))
return e==".rules"
end

function IsYamlFile(e)
   e=e or""
   local e=string.lower(string.sub(e,-5,-1))
   return e == ".yaml"
end

function IsYmlFile(e)
   e=e or""
   local e=string.lower(string.sub(e,-4,-1))
   return e == ".yml"
end

local groupnames, filename
local group_list = {}

filename = m.uci:get(openclash, "config", "config_path")
if filename then
   groupnames = SYS.exec(string.format('ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "YAML.load_file(\'%s\')[\'proxy-groups\'].each do |i| puts i[\'name\']+\'##\' end" 2>/dev/null',filename))
   if groupnames then
      for groupname in string.gmatch(groupnames, "([^'##\n']+)##") do
         if groupname ~= nil and groupname ~= "" then
            table.insert(group_list, groupname)
         end
      end
   end
end

m.uci:foreach("openclash", "groups",
   function(s)
      if s.name ~= "" and s.name ~= nil then
         table.insert(group_list, s.name)
      end
   end)

table.sort(group_list)
table.insert(group_list, "DIRECT")
table.insert(group_list, "REJECT")
table.insert(group_list, "REJECT-DROP")
table.insert(group_list, "PASS")
table.insert(group_list, "GLOBAL")

-- [[ Edit Game Rule ]] --
s = m:section(TypedSection, "game_config", translate("Game Rules Append"))
s.anonymous = true
s.addremove = true
s.sortable = true
s.template = "openclash/tblsection"
s.rmempty = false

---- enable flag
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty     = false
o.default     = o.enabled
o.cfgvalue    = function(...)
    return Flag.cfgvalue(...) or "1"
end

---- config
o = s:option(ListValue, "config", translate("Config File"))
o:value("all", translate("Use For All Config File"))
local e,a={}
for t,f in ipairs(fs.glob("/etc/openclash/config/*"))do
	a=fs.stat(f)
	if a then
    e[t]={}
    e[t].name=fs.basename(f)
    if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then
       o:value(e[t].name)
    end
  end
end

---- rule name
o = s:option(DynamicList, "rule_name", translate("Game Rule's Name"))
local e,a={}
for t,f in ipairs(fs.glob("/etc/openclash/game_rules/*"))do
	a=fs.stat(f)
	if a then
    e[t]={}
    e[t].filename=fs.basename(f)
    if IsRuleFile(e[t].filename) then
       e[t].name=string.gsub(luci.sys.exec(string.format("grep ',%s$' /usr/share/openclash/res/game_rules.list |awk -F ',' '{print $1}' 2>/dev/null",e[t].filename)), "[\r\n]", "")
       if e[t].name ~= "" and e[t].name ~= nil then
          o:value(e[t].name)
       end
    end
  end
end

o.rmempty = true

---- Proxy Group
o = s:option(ListValue, "group", translate("Select Proxy Group"))
o.rmempty = true
for _, groupname in ipairs(group_list) do
   o:value(groupname)
end

-- [[ Edit Other Rule Provider ]] --
s = m:section(TypedSection, "rule_provider_config", translate("Other Rule Providers Append"))
s.anonymous = true
s.addremove = true
s.sortable = true
s.template = "openclash/tblsection"
s.rmempty = false

---- enable flag
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty     = false
o.default     = o.enabled
o.cfgvalue    = function(...)
    return Flag.cfgvalue(...) or "1"
end

---- config
o = s:option(ListValue, "config", translate("Config File"))
o:value("all", translate("Use For All Config File"))
local e,a={}
for t,f in ipairs(fs.glob("/etc/openclash/config/*"))do
	a=fs.stat(f)
	if a then
    e[t]={}
    e[t].name=fs.basename(f)
    if IsYamlFile(e[t].name) or IsYmlFile(e[t].name) then
       o:value(e[t].name)
    end
  end
end

---- rule name
o = s:option(DynamicList, "rule_name", translate("Rule Provider's Name"))
local e,a={}
for t,f in ipairs(fs.glob("/etc/openclash/rule_provider/*"))do
	a=fs.stat(f)
	if a then
    e[t]={}
    e[t].filename=fs.basename(f)
    if IsYamlFile(e[t].filename) or IsYmlFile(e[t].filename) then
       e[t].name=string.gsub(luci.sys.exec(string.format("grep ',%s$' /usr/share/openclash/res/rule_providers.list |awk -F ',' '{print $1}' 2>/dev/null",e[t].filename)), "[\r\n]", "")
       if e[t].name ~= "" and e[t].name ~= nil then
          o:value(e[t].name)
       end
    end
  end
end

o.rmempty = true

---- Proxy Group
o = s:option(ListValue, "group", translate("Select Proxy Group"))
o.rmempty = true
for _, groupname in ipairs(group_list) do
   o:value(groupname)
end

o = s:option(Value, "interval", translate("Rule Providers Interval(s)"))
o.default = "86400"
o.rmempty = false

---- position
o = s:option(ListValue, "position", translate("Append Position"))
o.rmempty     = false
o:value("0", translate("Priority Match"))
o:value("1", translate("Extended Match"))

-- [[ Edit Custom Rule Provider ]] --
s = m:section(TypedSection, "rule_providers", translate("Custom Rule Providers Append"))
s.anonymous = true
s.addremove = true
s.sortable = true
s.template = "openclash/tblsection"
s.extedit = luci.dispatcher.build_url("admin/services/openclash/rule-providers-config/%s")
function s.create(...)
	local sid = TypedSection.create(...)
	if sid then
		luci.http.redirect(s.extedit % sid)
		return
	end
end

---- enable flag
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty     = false
o.default     = o.enabled
o.cfgvalue    = function(...)
    return Flag.cfgvalue(...) or "1"
end

o = s:option(DummyValue, "config", translate("Config File"))
function o.cfgvalue(...)
	return Value.cfgvalue(...) or translate("all")
end

o = s:option(DummyValue, "name", translate("Rule Providers Name"))
function o.cfgvalue(...)
	return Value.cfgvalue(...) or translate("None")
end

---- Proxy Group
o = s:option(ListValue, "group", translate("Select Proxy Group"))
o.rmempty = true
for _, groupname in ipairs(group_list) do
   o:value(groupname)
end

o = s:option(ListValue, "position", translate("Append Position"))
o.rmempty     = false
o:value("0", translate("Priority Match"))
o:value("1", translate("Extended Match"))

local rm = {
    {rule_mg, pro_mg}
}

rmg = m:section(Table, rm)

o = rmg:option(Button, "rule_mg", " ")
o.inputtitle = translate("Game Rules Manage")
o.inputstyle = "reload"
o.write = function()
  HTTP.redirect(DISP.build_url("admin", "services", "openclash", "game-rules-manage"))
end

o = rmg:option(Button, "pro_mg", " ")
o.inputtitle = translate("Other Rule Provider Manage")
o.inputstyle = "reload"
o.write = function()
  HTTP.redirect(DISP.build_url("admin", "services", "openclash", "rule-providers-manage"))
end

local t = {
    {Commit, Apply}
}

ss = m:section(Table, t)

o = ss:option(Button, "Commit", " ")
o.inputtitle = translate("Commit Settings")
o.inputstyle = "apply"
o.write = function()
  m.uci:commit("openclash")
end

o = ss:option(Button, "Apply", " ")
o.inputtitle = translate("Apply Settings")
o.inputstyle = "apply"
o.write = function()
  m.uci:set("openclash", "config", "enable", 1)
  m.uci:commit("openclash")
  SYS.call("/etc/init.d/openclash restart >/dev/null 2>&1 &")
  HTTP.redirect(DISP.build_url("admin", "services", "openclash"))
end

m:append(Template("openclash/toolbar_show"))

return m
