#!/usr/bin/env lua

local json = require "luci.jsonc"
local fs   = require "nixio.fs"
local sys = require "luci.sys"
local ut = require "luci.util"

local function readfile(path)
        local s = fs.readfile(path)
        return s and (s:gsub("^%s+", ""):gsub("%s+$", ""))
end

local methods = {
	getVpnName = {
		call = function()
			local sys = require "luci.sys"
			local uci = require "uci"
			local res = {}
			local vpns = {'l2tp', 'pptp', 'ipsec', 'openvpn', 'gre'}
			for k,v in pairs(vpns) do
				res[v] = {}
				if v == 'l2tp' then
					local vpnname = luci.sys.exec("uci show network | grep 'proto' | grep -e 'l2tp' | awk -F '.' '{print$2}' | xargs echo -n")
					for name in string.gmatch(vpnname, "%S+") do
						table.insert(res[v], name)
					end
				elseif v == 'pptp' then
					local vpnname = luci.sys.exec("uci show network | grep 'proto' | grep -e 'pptp' | awk -F '.' '{print$2}' | xargs echo -n")
					for name in string.gmatch(vpnname, "%S+") do
						table.insert(res[v], name)
					end
				elseif v == 'gre' then
					local vpnname = luci.sys.exec("uci show network | grep 'proto' | grep -e 'gre' | awk -F '.' '{print$2}' | xargs echo -n")
					for name in string.gmatch(vpnname, "%S+") do
						table.insert(res[v], name)
					end
				elseif v == 'ipsec' then
					local vpnname = luci.sys.exec("uci show ipsec | grep 'proto' | awk -F '.' '{print$2}' | xargs echo -n")
					for name in string.gmatch(vpnname, "%S+") do
						table.insert(res[v], name)
					end
				elseif v == 'openvpn' then
					local vpnname = luci.sys.exec("uci show openvpn | grep 'proto' | awk -F '.' '{print$2}' | xargs echo -n")
					for name in string.gmatch(vpnname, "%S+") do
						table.insert(res[v], name)
					end
				end
			end
			return { result = res }
		end
	}
}

local function parseInput()
        local parse = json.new()
        local done, err

        while true do
                local chunk = io.read(4096)
                if not chunk then
                        break
                elseif not done and not err then
                        done, err = parse:parse(chunk)
                end
        end

        if not done then
                print(json.stringify({ error = err or "Incomplete input" }))
                os.exit(1)
        end

        return parse:get()
end

local function validateArgs(func, uargs)
        local method = methods[func]
        if not method then
                print(json.stringify({ error = "Method not found" }))
                os.exit(1)
        end

        if type(uargs) ~= "table" then
                print(json.stringify({ error = "Invalid arguments" }))
                os.exit(1)
        end

        uargs.ubus_rpc_session = nil

        local k, v
        local margs = method.args or {}
        for k, v in pairs(uargs) do
                if margs[k] == nil or
                   (v ~= nil and type(v) ~= type(margs[k]))
                then
                        print(json.stringify({ error = "Invalid arguments" }))
                        os.exit(1)
                end
        end

        return method
end

if arg[1] == "list" then
        local _, method, rv = nil, nil, {}
        for _, method in pairs(methods) do rv[_] = method.args or {} end
        print((json.stringify(rv):gsub(":%[%]", ":{}")))
elseif arg[1] == "call" then
        local args = parseInput()
        local method = validateArgs(arg[2], args)
        local result, code = method.call(args)
        print((json.stringify(result):gsub("^%[%]$", "{}")))
        os.exit(code or 0)
end
