require("rsmdict")

--The Objects that is supported by the Script
local obj_ids = {
                   RSM.RSM_TagID.TAG_LOGIC_CFG,
                   RSM.RSM_TagID.TAG_LOGIC_INPUTS,
                   RSM.RSM_TagID.TAG_LOGIC_OUTPUTS                    
                }
      
local rules = {}  
           
local rulesPath = "/etc/rsm/gsmiodriver.xml"
local rule_file = ""

local testPath = "/usr/share/lua/kses/IOlogicTest.xml"

function print_table(t,p)

   for k,v in pairs(t) do
     print(p,k,v)
     if(type(v)=="table") then 
         print_table(v,p.."\t")
     end
  end
end

local escape_lua_pattern
  do
      local matches =
     {
          ["^"] = "%^";
          ["$"] = "%$";
          ["("] = "%(";
          [")"] = "%)";
          ["%"] = "%%";
          ["."] = "%.";
          ["["] = "%[";
          ["]"] = "%]";
          ["*"] = "%*";
          ["+"] = "%+";
          ["-"] = "%-";
          ["?"] = "%?";
          ["\0"] = "%z";
      }
  
      escape_lua_pattern = function(s)
          return (s:gsub(".", matches))
      end
  end


--Retuen the Object List
function getObjects()
 return obj_ids;
end

--Convert the config file into an object message nd return that.
--Actually supposed to check the request object to find the exact object if any to 
--return. We jippo that by always returning all of them
function getConfig(cfg)
  load_rules()
  msg = rules_to_msg()  
  return msg
end


--Function to lookup and set a specific object(s)
--and then to update the cofig file with those values
function setConfig(cfg)
   load_rules()   
   --print_table(rules,0)
   update_rules(cfg)
   store_rules()
end

function deleteConfig(cfg)
   load_rules()
   delete_rule(cfg)
end

function replaceConfig(cfg)
   
end


function command_exec(cmd)
  local f = io.popen(cmd) 
  value = f:read("*a") or "none"
  f:close()
  return value
end

function scandir(directory)
  local i, t, popen = 0, {}, io.popen
    for filename in popen('ls -a "'..directory..'"'):lines() do
        i = i + 1
        t[i] = filename
    end
    return t
end

function writefile(fileaddres,value)
  local f = io.open(fileaddres,"w+")
  f:write(value)
  f:close()
  return true
end

function load_rules() 
  --print("Loading pf data...")   
  --sf = command_exec("cat "..serial_conf_file)  
  countInputs = 0   
  countOutputs = 0
  rules = {}
  config = command_exec("cat "..rulesPath) 
  rule_file = config     
  for id, cfg in config:gmatch([[<connection%s+id=%"(.-)%"%s->(.-)</connection>]]) do
      ruleID = tonumber(id)
      rules[ruleID] = {}
      rules[ruleID].inputs = {}    
      rules[ruleID].outputs = {}      
      rules[ruleID].id = ruleID
      operation, trigger = cfg:match([[<trigger%s+operation=%"(.-)%"%s->(.-)</trigger>]])
      rules[ruleID].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
              rules[ruleID].inputs[countInputs] = {}
              rules[ruleID].inputs[countInputs].devtype = devtype
              rules[ruleID].inputs[countInputs].label = label
              rules[ruleID].inputs[countInputs].invert = invert  
              rules[ruleID].inputs[countInputs].id = ruleID
              
              countInputs = countInputs + 1    
          end
      end
      
      rules[ruleID].outputs[countOutputs] = {}
      attributes, action = cfg:match([[<action%s-(.-)%s->(.-)</action>]])
      
      if attributes ~= nil or attributes ~= "" then      
          --print("Attributes pattern match: "..attributes)
          rules[ruleID].outputs[countOutputs].invert = attributes:match([[operation=%"(.-)%"]]) or "NONINVERSE" 
          rules[ruleID].invert = rules[ruleID].outputs[countOutputs].invert      
      end
      if action ~= nil then
          devtype, label = action:match([[<detail%s+dev_type=%"(.-)%"%s+io_label=%"(.-)%"%s-/>]])
          rules[ruleID].outputs[countOutputs].devtype = devtype
          rules[ruleID].outputs[countOutputs].label = label
          rules[ruleID].outputs[countOutputs].id = ruleID
          
          countOutputs = countOutputs + 1
      end
      
  end  
  
  
   
              
end --function

function rules_to_msg()
  local msg = {}
  rule_ctr = 0
  
  --print("Load Message: ")
  
  --Load rule information into a message
  for idx,rf in pairs(rules) do     
     rule_cfg = {}
     
     rule_cfg.objid =  RSM.RSM_TagID.TAG_LOGIC_CFG
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_ID] = rf.id
     --rule_cfg[RSM.RSM_TagID.TAG_LOGIC_OPERATION] = rf.operation  
     
     if (rf.operation == "AND") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_OPERATION] = RSM.TAG_LOGIC_OPERATION_Types.TAG_LOGIC_OPERATION_AND
     elseif (rf.operation == "OR") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_OPERATION] = RSM.TAG_LOGIC_OPERATION_Types.TAG_LOGIC_OPERATION_OR     
     end      
                                      
        
     msg[rule_ctr] = rule_cfg
     rule_ctr = rule_ctr+1
     
     --Load inputs information into a message  
  for idx,inf in pairs(rf.inputs) do     
     rule_cfg = {}
     rule_cfg.objid =  RSM.RSM_TagID.TAG_LOGIC_INPUTS
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_ID] = inf.id
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_LABEL] = inf.label   
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = inf.devtype  
     
     if (inf.devtype == "UNKNOWN") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_UNKNOWN
        elseif (inf.devtype == "IO") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_IO
        elseif (inf.devtype == "AC") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_AC
        elseif (inf.devtype == "ANALOG") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG
        elseif (inf.devtype == "ANALOG_IO") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG_IO
        elseif (inf.devtype == "SNMP") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_SNMP
        elseif (inf.devtype == "MODBUS") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_MODBUS
        elseif (inf.devtype == "OTHER") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_OTHER
     end
     
     if (inf.invert == "false") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_NONINVERTED
     elseif (inf.invert == "true") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_INVERTED     
     end        
                  
     msg[rule_ctr] = rule_cfg
     rule_ctr = rule_ctr+1
  end
  
  --Load output information into a message
  for idx,outf in pairs(rf.outputs) do     
     rule_cfg = {}
     rule_cfg.objid =  RSM.RSM_TagID.TAG_LOGIC_OUTPUTS
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_ID] = outf.id
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_LABEL] = outf.label   
     rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = outf.devtype 
     
     if (outf.devtype == "UNKNOWN") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_UNKNOWN
        elseif (outf.devtype == "IO") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_IO
        elseif (outf.devtype == "AC") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_AC
        elseif (outf.devtype == "ANALOG") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG
        elseif (outf.devtype == "ANALOG_IO") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG_IO
        elseif (outf.devtype == "SNMP") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_SNMP
        elseif (outf.devtype == "MODBUS") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_MODBUS
        elseif (outf.devtype == "OTHER") then
           rule_cfg[RSM.RSM_TagID.TAG_LOGIC_TYPE] = RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_OTHER
     end 
     
     if (outf.invert == "NONINVERSE") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_NONINVERTED
     elseif (outf.invert == "INVERSE") then
        rule_cfg[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_INVERTED     
     end   
                  
     msg[rule_ctr] = rule_cfg
     rule_ctr = rule_ctr+1
  end
  end
  
  
  
       
  return msg
end

function update_rules(cfg)
    count_rules = 0
    count_inputs = 0
    count_outputs = 0    
    
   for idx,obj in pairs(cfg) do      
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_LOGIC_CFG then   --Config Tag                 
          if obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= '' then
              print("Incoming Rule ID: "..obj[RSM.RSM_TagID.TAG_LOGIC_ID])        
              --obj[RSM.RSM_TagID.TAG_BUS_SERIALNUM] = obj[RSM.RSM_TagID.TAG_BUS_SERIALNUM] .. ".xml"  
              
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] == nil then
                  print("New ID!")
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] = {}
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].new = 1
              end
              
              rf = rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]]              
              if rf then 
                  rf.id = obj[RSM.RSM_TagID.TAG_LOGIC_ID]                 
                  setrules(rf,obj)
              end                         
          end           
      end -- if cfg
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_LOGIC_INPUTS then  --Inputs tag                  
          if obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= '' or obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= nil then
              print("(Inputs) Incoming Rule ID: "..obj[RSM.RSM_TagID.TAG_LOGIC_ID])
              
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] == nil then
                  print("New ID!")
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] = {}
              end 
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs == nil then                  
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs = {}
              end  
              if count_inputs == 0 then                  
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs = {}
              end               
         
              --Testing nested arrays   
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs[count_inputs] == nil then
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs[count_inputs] = {}                  
              end                            
              inf = rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].inputs[count_inputs]
              if inf then 
                  inf.id = obj[RSM.RSM_TagID.TAG_LOGIC_ID]                 
                  setinputs(inf,obj)
              end
              --*******************                           
          else--New ccd profile
              print("Error: No rule ID provided..")                    
          end -- if filename       
          count_inputs = count_inputs + 1
      end -- if override 
      
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_LOGIC_OUTPUTS then  --Outputs tag                  
          if obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= '' or obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= nil then
              print("(Outputs) Incoming Rule ID: "..obj[RSM.RSM_TagID.TAG_LOGIC_ID])
              
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] == nil then
                  print("New ID!")
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]] = {}
              end   
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs == nil then                  
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs = {}
              end 
              if count_inputs == 0 then                  
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs = {}
              end                  
               
                            
                
                         
              --Testing nested arrays   
              if rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs[count_outputs] == nil then
                  rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs[count_outputs] = {}                  
              end                            
              outf = rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].outputs[count_outputs]
              if outf then          
                  outf.id = obj[RSM.RSM_TagID.TAG_LOGIC_ID]             
                  setoutputs(outf,obj)
              end
              --*******************                           
          else--New ccd profile
              print("Error: No rule ID provided..")                    
          end -- if filename       
          count_outputs = count_outputs + 1
      end -- if override 
      
      
      
       
   end -- for
end --function


function setrules(sf,obj)    
    
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_OPERATION] then
       if obj[RSM.RSM_TagID.TAG_LOGIC_OPERATION] == RSM.TAG_LOGIC_OPERATION_Types.TAG_LOGIC_OPERATION_AND then  
          sf.operation = "AND"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_OPERATION] == RSM.TAG_LOGIC_OPERATION_Types.TAG_LOGIC_OPERATION_OR then  
          sf.operation = "OR"
       end        
    end      
    
    sf.changed = 1
    
end

function setinputs(sf,obj)
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_LABEL] then
       sf.label = obj[RSM.RSM_TagID.TAG_LOGIC_LABEL]
    end 
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] then
       if obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] == RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_NONINVERTED then  
          sf.invert = "false"
       elseif obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] == RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_INVERTED then  
          sf.invert = "true"
       else
          sf.invert = "false"
       end
    else
       sf.invert = "false"         
    end  
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] then
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_UNKNOWN then  
          sf.devtype = "UNKNOWN"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_IO then  
          sf.devtype = "IO"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_AC then  
          sf.devtype = "AC"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG then  
          sf.devtype = "ANALOG"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG_IO then  
          sf.devtype = "ANALOG_IO"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_SNMP then  
          sf.devtype = "SNMP"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_MODBUS then  
          sf.devtype = "MODBUS"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_OTHER then  
          sf.devtype = "OTHER"
       end    
              
    end      
    
    sf.changed = 1
    rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].changed = 1
end

function setoutputs(sf,obj)   
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_LABEL] then
       sf.label = obj[RSM.RSM_TagID.TAG_LOGIC_LABEL]
    end 
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] then
       if obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] == RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_NONINVERTED then  
          sf.invert = "NONINVERSE"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_INVERSE] == RSM.TAG_LOGIC_INVERSE_Types.TAG_LOGIC_INVERSE_INVERTED then  
          sf.invert = "INVERSE"
       end        
       print("Setting output inverse to "..sf.invert)
       rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].invert = sf.invert
    end      
    
    if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] then
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_UNKNOWN then  
          sf.devtype = "UNKNOWN"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_IO then  
          sf.devtype = "IO"
       end 
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_AC then  
          sf.devtype = "AC"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG then  
          sf.devtype = "ANALOG"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_ANALOG_IO then  
          sf.devtype = "ANALOG_IO"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_SNMP then  
          sf.devtype = "SNMP"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_MODBUS then  
          sf.devtype = "MODBUS"
       end
       if obj[RSM.RSM_TagID.TAG_LOGIC_TYPE] == RSM.TAG_LOGIC_TYPE_Types.TAG_LOGIC_TYPE_OTHER then  
          sf.devtype = "OTHER"
       end              
       
    end      
    
    
    sf.changed = 1
    rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]].changed = 1
    
end


function store_rules()
    newXML=""
  for idx,rf in pairs(rules) do
      print("Storing: "..rf.id)
      
         if rf.changed and rf.changed == 1 then
            newXML = [[<connection id="]]..rf.id..[[">
 ]]
        --Operation        
        newXML = newXML .. [[    <trigger operation="]]..rf.operation..[[">
 ]]
 
         
        --Inputs
        if rf.inputs == nil then
            newXML = newXML .. [[
         <detail dev_type="" io_label="" io_invert=""/>
 ]]
        else
            for numIn, input in pairs(rf.inputs) do
                newXML = newXML .. [[
         <detail dev_type="]]..input.devtype..[[" io_label="]]..input.label..[[" io_invert="]]..input.invert..[["/>
 ]]
            end
        end
        
        
        newXML = newXML .. [[
     </trigger>
 ]]
        --Invert
        if rf.invert == nil then
            newXML = newXML .. [[
     <action>
 ]]
        else
            print("Testing output invert value: "..rf.invert)
            if rf.invert == 'INVERSE' then
                newXML = newXML .. [[
     <action operation="INVERSE">
 ]]
            else
                newXML = newXML .. [[
     <action>
 ]]
            end
        end
        
        
        --Outputs
        if rf.outputs == nil then
            newXML = newXML .. [[
         <detail dev_type="" io_label=""/>
     </action>
 </connection>
 ]] 
        else
            for numOut, output in pairs(rf.outputs) do        
                newXML = newXML .. [[
         <detail dev_type="]]..output.devtype..[[" io_label="]]..output.label..[["/>
     </action>
 </connection>]] 
            end  
        end
          
  
 
          if rule_file:match([[<connection id="]]..rf.id..[[">]]) then
              rule_file = rule_file:gsub([[<connection id="]]..rf.id..[[">.-</connection>]], newXML)        
          else
              rule_file = rule_file:gsub("</io_connections>",newXML.."\n</io_connections>")    
          end
             
            
         end--changed if       
  end --rule pairs loop
  
  command_exec("sv stop gsmiodriver") 
  writefile(rulesPath,rule_file)
  print("Writing new xml file...")
  --writefile(testPath,rule_file)
  command_exec("sv start gsmiodriver") 

end--function loop

function delete_rule(cfg)
    
   for idx,obj in pairs(cfg) do      
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_LOGIC_CFG then   --Config Tag                 
          if obj[RSM.RSM_TagID.TAG_LOGIC_ID] ~= '' then
              
              sf = rules[obj[RSM.RSM_TagID.TAG_LOGIC_ID]]              
              if sf then                  
                  delRule(sf,obj)
              end                           
          else                    
              print("Error: No ID provided to delete!")               
          end -- if filename       
          
      end -- if cfg
   end
end--function

function delRule(rf,obj)
    
    
--    rule_file = command_exec("cat "..rulesPath)
--    --change to how web-module does it TODO
--    if rule_file:match([[n>.-<connection id="]]..rf.id..[[">]]) then
--        print("Replace last")
--        newXML='</connection>'
--        rule_file = rule_file:gsub([[</connection>.-<connection id="]]..rf.id..[[">.-</connection>]], newXML)
--    elseif rule_file:match([[">.-<connection id="]]..rf.id..[[">]]) then 
--        print("Replace 1st") 
--        newXML='>'
--        rule_file = rule_file:gsub([[>.-<connection id="]]..rf.id..[[">.-</connection>]], newXML)
--    end 
    
    
    local ioconfig = command_exec("cat "..rulesPath) or ""
    tmpcon = ioconfig:match([[%s-<connection id="]]..rf.id..[[">.-</connection>%s-]]) or ""
    if (tmpcon ~= "") then
      newconfig = ioconfig:gsub(escape_lua_pattern(tmpcon), "")
      command_exec("sv stop gsmiodriver") 
      print("ReWriting new xml file...")
      writefile(rulesPath, newconfig)
      command_exec("sv start gsmiodriver") 
    end
    
    
  --[[command_exec("sv stop gsmiodriver") 
  writefile(rulesPath,rule_file)
  print("ReWriting new xml file...")
  --writefile(testPath,rule_file)
  command_exec("sv start gsmiodriver") ]]--
    
end



--Testing....

--print("Testing...")

--load_rules()
--print("Rules Table: ")
--print_table(rules,0)

--[[print("Fanoutputs Table: ")
print_table(fanoutputs,0)
print("Aircons Table: ")
print_table(aircons,0)]]--
--print("Get Config...............")
--print_table(getConfig(),0)
--print("Rules Table: ")
--print_table(rules,0)

local testCfg = {}
local obj ={}
local obj1 ={}
local obj2 ={}
local obj3 ={}
local obj4 ={}
local obj5 ={}
local obj6 ={}

local obj7 ={}
local obj8 ={}
local obj9 ={}
local obj10 ={}
local obj11 ={}
local obj12 ={}

local obj13 ={}

obj.objid = RSM.RSM_TagID.TAG_LOGIC_CFG
obj[RSM.RSM_TagID.TAG_LOGIC_ID] = 4
obj[RSM.RSM_TagID.TAG_LOGIC_OPERATION] = 1

obj1.objid = RSM.RSM_TagID.TAG_LOGIC_INPUTS
obj1[RSM.RSM_TagID.TAG_LOGIC_ID] = 4
obj1[RSM.RSM_TagID.TAG_LOGIC_LABEL] = "P23"
obj1[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = 1
obj1[RSM.RSM_TagID.TAG_LOGIC_TYPE] = 7

obj2.objid = RSM.RSM_TagID.TAG_LOGIC_OUTPUTS
obj2[RSM.RSM_TagID.TAG_LOGIC_ID] = 2
obj2[RSM.RSM_TagID.TAG_LOGIC_LABEL] = "OUTPUT_3"
obj2[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = 1
obj2[RSM.RSM_TagID.TAG_LOGIC_TYPE] = 3

obj3.objid = RSM.RSM_TagID.TAG_LOGIC_INPUTS
obj3[RSM.RSM_TagID.TAG_LOGIC_ID] = 2
obj3[RSM.RSM_TagID.TAG_LOGIC_LABEL] = "P23"
obj3[RSM.RSM_TagID.TAG_LOGIC_INVERSE] = 1
obj3[RSM.RSM_TagID.TAG_LOGIC_TYPE] = 7

obj4.objid = RSM.RSM_TagID.TAG_LOGIC_CFG
obj4[RSM.RSM_TagID.TAG_LOGIC_ID] = 3

obj5.objid = RSM.RSM_TagID.TAG_CCD_AC
obj5[RSM.RSM_TagID.TAG_CCD_FILENAME] = "testccd.xml"
obj5[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 2
obj5[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestACOutput2"

obj13.objid = RSM.RSM_TagID.TAG_CCD_FAN
obj13[RSM.RSM_TagID.TAG_CCD_FILENAME] = "testccd.xml"
obj13[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 0
obj13[RSM.RSM_TagID.TAG_CCD_LABEL] = "Test1 Output2"

--Add new profile
obj6.objid = RSM.RSM_TagID.TAG_CCD_CFG
obj6[RSM.RSM_TagID.TAG_CCD_FILENAME] = ""
obj6[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestNewProfile"
obj6[RSM.RSM_TagID.TAG_CCD_TEMP] = 20
obj6[RSM.RSM_TagID.TAG_CCD_RANGE] = 0
obj6[RSM.RSM_TagID.TAG_CCD_INTERNAL] = "Test Internal_new"
obj6[RSM.RSM_TagID.TAG_CCD_EXTERNAL] = "Test External_new"
obj6[RSM.RSM_TagID.TAG_CCD_ACMONITOR] = "Test ACmonitor_new"
obj6[RSM.RSM_TagID.TAG_CCD_DELTA] = 0
obj6[RSM.RSM_TagID.TAG_CCD_FAN_TYPE] = 0

obj7.objid = RSM.RSM_TagID.TAG_CCD_OVERRIDE
obj7[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj7[RSM.RSM_TagID.TAG_CCD_LABEL] = "testOverrideLabel_new"

obj8.objid = RSM.RSM_TagID.TAG_CCD_FAN
obj8[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj8[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 0
obj8[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestFan1 Output_new"

obj9.objid = RSM.RSM_TagID.TAG_CCD_FAN
obj9[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj9[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 1
obj9[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestFan2 Output_new"

obj10.objid = RSM.RSM_TagID.TAG_CCD_FAN
obj10[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj10[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 0
obj10[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestFan1 Output2_new"

obj11.objid = RSM.RSM_TagID.TAG_CCD_AC
obj11[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj11[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 1
obj11[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestACOutput1_new"

obj12.objid = RSM.RSM_TagID.TAG_CCD_AC
obj12[RSM.RSM_TagID.TAG_CCD_FILENAME] = "TestNewProfile.xml"
obj12[RSM.RSM_TagID.TAG_CCD_PRIORITY] = 2
obj12[RSM.RSM_TagID.TAG_CCD_LABEL] = "TestACOutput2_new"


--testCfg[0] = obj
--testCfg[1] = obj1
--testCfg[0] = obj2
--testCfg[0] = obj3
--testCfg[0] = obj4
--testCfg[5] = obj5

--testCfg[6] = obj6
--testCfg[7] = obj7
--testCfg[8] = obj8
--testCfg[9] = obj9
--testCfg[10] = obj10
--testCfg[11] = obj11
--testCfg[12] = obj12
--testCfg[2] = obj13

--setConfig(testCfg)
--deleteConfig(testCfg)




























