#!/usr/bin/lua

local json = require("luci.jsonc")

local function sh(cmd)
    local h = io.popen(cmd .. " 2>&1")
    local out = h:read("*a")
    local ok = h:close()
    return ok, out
end

local function get_servers()
    local h = io.popen("uci -q get dhcp.@dnsmasq[0].server 2>/dev/null")
    local out = h:read("*a") or ""
    h:close()
    local list = {}
    for s in out:gmatch("%S+") do list[#list+1] = s end
    return list
end

local function get_noresolv()
    local h = io.popen("uci -q get dhcp.@dnsmasq[0].noresolv 2>/dev/null")
    local out = (h:read("*a") or ""):gsub("%s+", "")
    h:close()
    return out == "1"
end

local function read_state()
    return {
        noresolv = get_noresolv(),
        servers = get_servers(),
    }
end

io.write("Content-Type: application/json\r\n\r\n")

local body = io.read("*a") or ""
local req = json.parse(body) or {}
local action = req.action or "status"

local ADGUARD = "127.0.0.1#5335"

if action == "status" then
    io.write(json.stringify({ ok = true, state = read_state() }))
    os.exit(0)
end

local function set_noresolv(v)
    sh("uci set dhcp.@dnsmasq[0].noresolv='" .. (v and "1" or "0") .. "'")
end

local function clear_servers()
    sh("uci -q delete dhcp.@dnsmasq[0].server")
end

local function add_server(s)
    sh("uci add_list dhcp.@dnsmasq[0].server='" .. s .. "'")
end

local function apply()
    sh("uci commit dhcp")
    sh("/etc/init.d/dnsmasq restart")
end

if action == "normal" then
    clear_servers()
    add_server(ADGUARD)
    set_noresolv(true)
    apply()

elseif action == "portal" then
    clear_servers()
    set_noresolv(false)
    apply()

elseif action == "set" then
    if req.noresolv ~= nil then set_noresolv(req.noresolv and true or false) end
    if req.servers ~= nil then
        clear_servers()
        for _, s in ipairs(req.servers) do
            if s and s ~= "" then add_server(s) end
        end
    end
    apply()

else
    io.write(json.stringify({ ok = false, error = "unknown action: " .. tostring(action) }))
    os.exit(0)
end

io.write(json.stringify({ ok = true, action = action, state = read_state() }))
