#!/opt/lnxall_app/bin/lua

local invoker = require "invoker"
local gfmt = string.format

local function local_writefile(fpath, fdata)
	local fh = io.open(fpath, "wb")
	if fh then
		local okay = fh:write(fdata)
		fh:close(); fh = nil
		if okay then return true end
		io.stderr:write(gfmt("Error, failed to write file: %s\n", fpath))
	else
		io.stderr:write(gfmt("Error, failed to open file: %s\n", fpath))
	end
	io.stderr:flush()
	return false
end

local function gpio_4gpower_onoff(self, onoff)
	if not invoker.statfile(self.value_path) then
		local_writefile("/sys/class/gpio/export", gfmt("%d\n", self.gpio_num))
		local_writefile(gfmt("/sys/class/gpio/gpio%d/direction", self.gpio_num), "out\n")
	end

	local buf_onoff = gfmt("%d\n", onoff and self.poweron_val or self.poweroff_val)
	return local_writefile(self.value_path, buf_onoff)
end

local function gpio_4gpower_ison(self)
	local val = invoker.readfile(self.value_path, invoker.TRIMEND)
	if val then val = tonumber(val) end
	if val == self.poweron_val then return true end
	if val == self.poweroff_val then return false end
	io.stderr:write(gfmt("Error, unknown GPIO value: %s\n", self.value_path))
	io.stderr:flush()
	return nil
end

local function common_4gpower_onoff(self)
	return true
end

local function common_4gpower_ison(self)
	return true
end

local function common_func_netdev(self)
	local ndevs = { "usb0", "modem0", "enp0s20f0u7", "ppp0" }
	for _, ndev in ipairs(ndevs) do
		if invoker.invoke(invoker.NOSTDIO, "ip", "link", "show", "dev", ndev) == 0 then
			return ndev
		end
	end
	return nil
end

local function rk3568_platform_func()
	local platobj = {
		name = "RK3568",
		gpio_num = 74,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function rk3588_platform_func()
	local platobj = {
		name = "RK3588",
		gpio_num = 120,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function rk3568_forlinx_func()
	local platobj = {
		name = "RK3568_FORLINX",
		gpio_num = 101,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function imx6ul_lc100_func()
	local platobj = {
		name = "iMX6UL",
		gpio_num = 132,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function wl2004_platform_func()
	local platobj = {
		name = "WL2004",
		gpio_num = 134,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function moxa_vm1220t_func()
	local platobj = {
		name = "VM1220T",
		gpio_num = 342,
		poweron_val = 0,
		poweroff_val = 1,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function yanhua_ecu1170_func()
	local platobj = {
		name = "ECU1170",
		gpio_num = 98,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function xintang_ma35d1_func()
	local platobj = {
		name = "MA35D1",
		gpio_num = 113,
		poweron_val = 1,
		poweroff_val = 0,
	}
	platobj.value_path = gfmt("/sys/class/gpio/gpio%d/value", platobj.gpio_num)

	local mtab = { ["poweron"] = gpio_4gpower_onoff,
		["ison"] = gpio_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local function common_platform_func()
	local platobj = {
		name = "common",
	}

	local mtab = { ["poweron"] = common_4gpower_onoff,
		["ison"] = common_4gpower_ison, ["netdev"] = common_func_netdev }
	setmetatable(platobj, { __index = mtab })
	return platobj
end

local platform_4gfunc = {
	['WLOSANY_RK3568'] = rk3568_platform_func,
	['WLOSANY_RK3568_XDDL'] = rk3568_platform_func,
	['WLOSANY_EMS1000E'] = rk3568_platform_func,
	['WLOSANY_RK3588'] = rk3588_platform_func,
	['WLOSANY_RK3568_FORLINX'] = rk3568_forlinx_func,
	['WLOSANY_LC100'] = imx6ul_lc100_func,
	['WLOSANY_VM1220T'] = moxa_vm1220t_func,
	['WLOSANY_X86_V3'] = common_platform_func,
	['WLOSANY_BAU-B30-003'] = common_platform_func,
	['WLOSANY_WooLink2004'] = wl2004_platform_func,
	['WLOSANY_ECU1170'] = yanhua_ecu1170_func,
	['WLOSANY_MA35D1'] = xintang_ma35d1_func,
}

local function detect_platform()
	local bnfile = '/tmp/sysinfo/board_name'
	local bname = invoker.readfile(bnfile, invoker.TRIMEND)
	if not bname or string.len(bname) == 0 then
		io.stderr:write(gfmt("Error, failed to read file: %s\n", bnfile))
		io.stderr:flush()
		return nil
	end

	local func = platform_4gfunc[bname]
	if not func then
		io.stderr:write(gfmt("Error, unsupported boardname: %s\n", bname))
		io.stderr:flush()
		return nil
	end

	local platobj = func()
	return platobj
end

-- return Lua module entry table
return { ["detect"] = detect_platform }
