local gsmio_conf = require("config/gsmio_conf")
local command = require("luamods/command")
local layout = require("luamods/layout")
local rsm_conf = require("config/rsm_conf")
local db = require("luamods/db")

--TAG_MSG_INFO TAG_MSG_INFO_IDX_ONLY

response = command.ex(rsm_conf.rsmc_path.." GET: TAG_MSG_INFO TAG_MSG_INFO_IDX_ONLY TAG_DEV_CFG") or ""
inputs = {}
outputs = {}
analogs = {}

if (response ~= "") then
    for id in response:gmatch("TAG_DEV_CFG%s+TAG_DEV_ID=(%x+)%s-") do
        devCfg = command.ex(rsm_conf.rsmc_path.." GET: TAG_IP_CFG TAG_DEV_ID="..id)
        if (devCfg ~= nil) then
            for inputCfg in devCfg:gmatch("TAG_IP_CFG%s+(.-)%s+TAG_IO_TYPE=01") do
                input = {}
                input.devID = id
                input.pnum = inputCfg:match("TAG_IO_PNUM=(%x+)")
                input.label = inputCfg:match([[TAG_IO_LABEL=%"(.-)%"]]) or "unknown"
                table.insert(inputs, input)
            end
        end
        devCfg = command.ex(rsm_conf.rsmc_path.." GET: TAG_OP_CFG TAG_DEV_ID="..id)
        if (devCfg ~= nil) then
            for outputCfg in devCfg:gmatch("TAG_OP_CFG%s+(.-)%s+TAG_IO_TYPE=02") do
                output = {}
                output.devID = id
                output.pnum = outputCfg:match("TAG_IO_PNUM=(%x+)")
                output.label = outputCfg:match([[TAG_IO_LABEL=%"(.-)%"]]) or "unknown"
                table.insert(outputs, output)
            end
        end        
        devCfg = command.ex(rsm_conf.rsmc_path.." GET: TAG_AI_CFG TAG_DEV_ID="..id)
        if (devCfg ~= nil) then
            for outputCfg in devCfg:gmatch("TAG_AI_CFG%s+(.-)%s+TAG_IO_TYPE=03") do
                analog = {}
                analog.devID = id
                analog.pnum = outputCfg:match("TAG_IO_PNUM=(%x+)")
                analog.label = outputCfg:match([[TAG_IO_LABEL=%"(.-)%"]]) or "unknown"
                table.insert(analogs, analog)
            end
        end        

    end
end

header = layout.getHeader()
footer = layout.getFooter()

userLevel = db.getPriv(layout.username) or 1

if (userLevel == 1) then
    buttonControl = " disabled"
    inputControl = " readonly"
else
    buttonControl = ""
    inputControl = ""
end

config = command.ex([[cat ]]..gsmio_conf.iodriver_xml) or ""
gsmconfig = command.ex([[cat ]]..gsmio_conf.iodriver_gsm_xml) or ""

gsmlabels = {}
if (gsmconfig ~= "") then
    for label in gsmconfig:gmatch([[<Label%s+name=%"(.-)%".->]]) do
        table.insert(gsmlabels, label)
    end
end

connections = {}
if (config ~= "") then
    for id, cfg in config:gmatch([[<connection%s+id=%"(.-)%"%s->(.-)</connection>]]) do
        if (cfg ~= nil) then
            con = {}
            con.inputs = {}
            con.output = {}
            con.id = id or "unknown"
            operation, trigger = cfg:match([[<trigger%s+operation=%"(.-)%"%s->(.-)</trigger>]])
            con.operation = operation or "AND"
            if (trigger ~= nil) then
                for devtype, label, invert in trigger:gmatch([[<detail%s+dev_type=%"(.-)%"%s+io_label=%"(.-)%"%s+io_invert=%"(.-)%"%s-/>]]) do
                    input = {}
                    input.devtype = devtype
                    input.label = label
                    input.invert = invert
                    input.matched = 0
                    input.icon = "<img src=\"images/warning.png\" alt=\"Unknown port\" title=\"Unknown port\"/>"
                    for i,inp in ipairs(inputs) do
                        if (label == inp.label) then
                            input.matched = 1
                            input.icon = ""
                            break
                        end
                    end
                    for i,inp in ipairs(outputs) do
                        if (label == inp.label) then
                            input.matched = 1
                            input.icon = ""
                            break
                        end
                    end
                    for i,inp in ipairs(analogs) do
                        if (label == inp.label) then
                            input.matched = 1
                            input.icon = ""
                            break
                        end
                    end
                    
                    if (input.matched == 0) then
                        for i,gsmlabel in ipairs(gsmlabels) do
                            if (label == gsmlabel) then
                                input.matched = 2
                                input.icon = "<img src=\"images/gsm.png\" alt=\"GSM Input\" title=\"GSM Input\"/>"
                                break
                            end
                        end
                    end

                    table.insert(con.inputs, input)
                end
            end
            attributes, action = cfg:match([[<action%s-(.-)%s->(.-)</action>]])
            if (attributes ~= nil) then
                operation = attributes:match([[operation=%"(.-)%"]])
                con.output.operation = operation
            end
            if (action ~= nil) then
                devtype, label = action:match([[<detail%s+dev_type=%"(.-)%"%s+io_label=%"(.-)%"%s-/>]])
                con.output.devtype = devtype
                con.output.label = label
                con.output.matched = 0
                con.output.icon = "<img src=\"images/warning.png\" alt=\"Unknown output\" title=\"Unknown output\"/>"
                for i,out in ipairs(outputs) do
                    if (label == out.label) then
                        con.output.matched = 1
                        con.output.icon = ""
                        break
                    end
                end                
                if (con.output.matched == 0) then
                    for i,gsmlabel in ipairs(gsmlabels) do
                        if (label == gsmlabel) then
                            con.output.matched = 2
                            con.output.icon = "<img src=\"images/gsm.png\" alt=\"GSM output\" title=\"GSM output\"/>"
                            break
                        end
                    end
                end
            end
        end
        table.insert(connections, con)
    end
end

content = ""

content = content .. [[
                    <div id="info">
                        <div style="background:url(images/iodriver.png); background-size:32px; background-repeat:no-repeat; background-position: 20px center;">
                            <center><h1>IO Logic Engine</h1></center>
                        </div>
                    </div>
]]

if (response == "") then
    content = content .. [[
                    <div id="info">
                        <center>
                            <h2><img src="images/warning.png"/> Invalid response</h2>
                            The RSM client ]]..rsm_conf.rsmc_path..[[ is missing, not responding or returned an invalid reply.<br><br>
                            Cannot confirm validity of connection I/Os.
                        </center>
                    </div> 
    ]]                    
end

if (config == "") then
    content = content .. [[
                    <div id="info">
                        <center>
                            <h2><img src="images/warning.png"/> Cannot read config file</h2>
                            The GSM/IO driver configuration file "]]..gsmio_conf.iodriver_xml..[[" is missing or unreadable.<br>
                        </center>
                    </div>
]]
    html = header..content..footer
    print(html)
    os.exit()
end

if (userLevel == 1) then
    content = content .. [[
                    <center><b>Note:</b> Editing this section requires administrator privileges.</center><br>
]]
end

content = content .. [[
                    <br>
                    <center>
                        <b>This is a list of the configured rules for the IO driver logic engine.<br><br>
                        Click the edit button for a rule to manage it.</b>
                    </center>
                    <br>
                    <div class="formLayoutfull">
]]
for i,con in ipairs(connections) do
    content = content .. [[
                        <b>Rule ]]..i..[[</b><br>
                        <table class="onetwo" style="text-align: center;">
                            <tr>
                                <th width="30%">Inputs</th>
                                <th width="14%">Operation</th>
                                <th width="30%">Output</th>
                                <th width="13%">Invert</th>
                                <th width="13%">Manage</th>
                            </tr>
                            <tr>
]]
    if (con.inputs[1] ~= nil) then
      if (con.inputs[1].invert == "true") then
            content = content .. [[
                                <td>! ]]..(con.inputs[1].label)..(con.inputs[1].icon)..[[</td>
]]
      else
            content = content .. [[
                                <td> ]]..(con.inputs[1].label)..(con.inputs[1].icon)..[[</td>
]]
      end
    else
        content = content .. [[
                                <td>-</td>
]]
    end
    content = content .. [[
                                <td style="vertical-align: middle;" rowspan="]] .. #(con.inputs) .. [[">]]..(con.operation)..[[</td>
                                <td style="vertical-align: middle;" rowspan="]] .. #(con.inputs) .. [[">
]]
        content = content .. [[
                                ]]..(con.output.label)..(con.output.icon)..[[
]]                                    

content = content .. [[
                                </td>
                                <td style="vertical-align: middle;" rowspan="]] .. #(con.inputs) .. [[">
]]
    if (con.output.operation == "INVERSE") then
        content = content .. [[
                                    YES
]]            
    end
    content = content .. [[                                
                                </td>
                                <td style="vertical-align: middle;" rowspan="]] .. #(con.inputs) .. [[">
                                    <form action="io_logic_edit.lua" method="POST">
                                        <input type="submit" name="editButton" value="Edit" style="width: 80%;"/>
                                        <input type="hidden" name="id" value="]]..con.id..[["/>
                                    </form>
                                </td>
                            </tr>
]]

for i = 2,#(con.inputs) do
      if (con.inputs[i].invert == "true") then
            content = content .. [[
                                <td>! ]]..(con.inputs[i].label)..(con.inputs[i].icon)..[[</td>
]]
      else
            content = content .. [[
                                <td> ]]..(con.inputs[i].label)..(con.inputs[i].icon)..[[</td>
]]   
      end   
    content = content .. [[
                            </tr>
]]
end

    content = content .. [[
                        </table>
                        <br>
]]
end
content = content .. [[
                        <hr>
                        <br>
                        <form action="io_logic_edit.lua" method="POST">
                            <input type="submit" name="newButton" value="Create New Rule"]]..buttonControl..[[/>
                        </form>
                    </div>
]]

content = content .. [[
                    <script>
                        function toggleVis(target)
                        {
                            if (target.style.display == "none")
                            {
                                target.style.display = "inline-block";
                            }
                            else
                            {
                                target.style.display = "none";
                            }
                            return false;
                        }
                    </script>
]]

config = config:gsub("<","&lt;")
config = config:gsub(">","&gt;")
content = content .. [[    
                    <br><img src="images/magnify.png"/> <a href="javascript:void(0)" onclick="toggleVis(document.getElementById('ioconfig'));">View ]]..gsmio_conf.iodriver_xml..[[</a></a><br>
        
                    <div id="ioconfig" style="display: none;">
                        <pre class="formLayoutfull">
]]..config..[[
                        </pre>
                    </div>    
]]                    

print(header..content..footer)
