require("rsmdict")
lfs = require("lfs")

--The Objects that is supported by the Script
local obj_ids = {
                   RSM.RSM_TagID.TAG_NET_IF_CFG 
                }
local interfaces = {}
local interface_file = ""
local interfaces_conf_path = "/etc/netctl"
local web_modules_path = "/srv/http/modsxml"

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


--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_interfaces()
  msg = interfaces_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_interfaces()
   update_interfaces(cfg)
   store_interfaces()
end


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

function log(message)
  command_exec("logger -t btm "..message)
end

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

function getWebModules()
  log("getWebModules:")
  for file in lfs.dir(web_modules_path) do
    log(" - "..file)
  end
end

function load_interfaces()
  interfaceCount = 0
  vlanCount = 0
  nextvlanid = 100
  for file in lfs.dir(interfaces_conf_path) do
    local f = interfaces_conf_path..'/'..file
    local attr = lfs.attributes (f)
    if attr.mode ~= "directory" then
      interfaceCount = interfaceCount + 1
      interface = file
      interfaces[interface] = {}
      interfaces[interface].name = file
      config = command_exec("cat "..f)
      interfaces[interface].config = config
      interfaces[interface].method = config:match("[^#]IP=(.-)\n") or "none"
      interfaces[interface].type = config:match("[^#]Connection=(.-)\n")
      if interfaces[interface].type == "mobile_ppp" then
        interfaces[interface].method = "ppp"
      end
      if interfaces[interface].type == "vlan" then
         --Suck some VLAN specific stuff
         interfaces[interface].vlanid = config:match("[^#]VLANID=(.-)\n")
         interfaces[interface].vlaninterface = config:match("[^#]BindsToInterfaces=(.-)\n") or ""
         interfaces[interface].parent = config:match("[^#]After=%('(.-)'%)\n") or ""
      end
      interfaces[interface].address = config:match("[^#]Address=%('(.-)/(.-)'%)\n") or config:match("[^#]Address=\"(.-)/(.-)\"\n") or nil
      interfaces[interface].netmask = config:match("[^#]Address=%('.-/(.-)'%)\n") or config:match("[^#]Address=\".-/(.-)\"\n") or nil
      interfaces[interface].gateway = config:match("[^#]Gateway='(.-)'\n") or nil
      interfaces[interface].enabled = command_exec("netctl is-enabled "..file):match("(enabled)") or ""
      interfaces[interface].interface = config:match("[^#]Interface=(.-)\n") or ""
      if interfaces[interface].type ~= "vlan" then
         interfaceCount = interfaceCount +1
      else
         if tonumber(interfaces[interface]) >= nextvlanid then
            nextvlanid = tonumber(interfaces[interface].vlanid) + 1
         end
         vlanCount = vlanCount +1
      end
    end
  end
end

function update_interfaces(cfg)
   for idx,obj in pairs(cfg) do
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_NET_IF_CFG then
          if obj[RSM.RSM_TagID.TAG_NET_IF_NAME] then
              intf = interfaces[obj[RSM.RSM_TagID.TAG_NET_IF_NAME]]
              if intf then
                setinterface(intf,obj)
              end
          end 
      end
   end 
end

function setinterface(intf,obj)
    intf.address=""
    intf.gateway=""
    intf.netmask=""
    if obj[RSM.RSM_TagID.TAG_NET_IF_ADDRESS] then
       intf.address = obj[RSM.RSM_TagID.TAG_NET_IF_ADDRESS]
    end
    if obj[RSM.RSM_TagID.TAG_NET_IF_GATEWAY] then
       intf.gateway = obj[RSM.RSM_TagID.TAG_NET_IF_GATEWAY]
    end
    if obj[RSM.RSM_TagID.TAG_NET_IF_NETMASK] then
       intf.netmask = obj[RSM.RSM_TagID.TAG_NET_IF_NETMASK]
    end
    if obj[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] then
       if obj[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] == RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_STATIC then  
          intf.method = "static"
       end    
       if obj[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] == RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_DHCP then  
          intf.method = "dhcp"
       end    
       if obj[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] == RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_PPP then  
          intf.method = "ppp"
       end    
    end
    if obj[RSM.RSM_TagID.TAG_NET_PRIORITY] then
        intf.enabled = "disabled"
	log("PRIORITY: "..obj[RSM.RSM_TagID.TAG_NET_PRIORITY])
      if(obj[RSM.RSM_TagID.TAG_NET_PRIORITY] == "enabled") then
        intf.enabled = "enabled"
      end
    end
    intf.changed = 1
end

function store_interfaces()
  for idx,intf in pairs(interfaces) do

    local currIntf = command_exec("cat "..interfaces_conf_path.."/"..intf.name)
    local newMethod = "static"

    if (intf.method == "dhcp") then
      newMethod = "dhcp"
    end
    if intf.address and intf.address ~= "" then
      if intf.netmask and intf.netmask ~= "" then
        currIntf = currIntf:gsub("#Address","Address")
        currIntf = currIntf:gsub("Address=.-\n","Address=('"..intf.address.."/"..intf.netmask.."')\n")   
      end
    end
    currIntf = currIntf:gsub("IP=.-\n","IP="..newMethod.."\n")
    currIntf = currIntf:gsub("#Gateway","Gateway")

    if intf.gateway and intf.gateway ~= "" then
      currIntf = currIntf:gsub("Gateway=.-\n","Gateway='"..intf.gateway.."'\n")
    else
      currIntf = currIntf:gsub("Gateway=.-\n","#Gateway=\n")
    end
    
    if intf.type == "wwan" then
      if newAPN ~= "" then
        currIntf = currIntf:gsub("#AccessPointName","AccessPointName")
        currIntf = currIntf:gsub("AccessPointName=.-\n","AccessPointName="..newAPN.."\n")
      else
        currIntf = currIntf:gsub("[^#]AccessPointName","\n#AccessPointName")
      end
    

      if newUser ~= "" then
        currIntf = currIntf:gsub("#User","User")
        currIntf = currIntf:gsub("User=.-\n","User='"..newUser.."'\n")
      else
        currIntf = currIntf:gsub("[^#]User","\n#User")
      end
    
      if newPasswd ~= "" then
        currIntf = currIntf:gsub("#Password","Password")
        currIntf = currIntf:gsub("Password=.-\n","Password='"..newPasswd.."'\n")
      else
        currIntf = currIntf:gsub("[^#]Password","\n#Password")
      end
    end

    if intf.changed and intf.changed == 1 then

      log("Restart "..intf.name.." - Enabled: "..intf.enabled)

      if (intf.enabled == "enabled") then
        command_exec("netctl enable "..intf.name)
      else
        command_exec("netctl disable "..intf.name)
      end

      command_exec("netctl restart "..intf.name)
    end  

    writefile(interfaces_conf_path.."/"..intf.name, currIntf)
  end
end  

function interfaces_to_msg()
  local msg = {}
  if_ctr = 0
  for idx,intf in pairs(interfaces) do
     local if_cfg = {}
     if_cfg.objid =  RSM.RSM_TagID.TAG_NET_IF_CFG
     if_cfg[RSM.RSM_TagID.TAG_NET_IF_NAME] = intf.name
     if intf.address  then 
       if_cfg[RSM.RSM_TagID.TAG_NET_IF_ADDRESS] = intf.address
     end
     if intf.netmask  then 
       if_cfg[RSM.RSM_TagID.TAG_NET_IF_NETMASK] = intf.netmask
     end
     if intf.gateway  then 
       if_cfg[RSM.RSM_TagID.TAG_NET_IF_GATEWAY] = intf.gateway
     end
     if intf.method  then 
        if (intf.method == "static") then
           if_cfg[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] = RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_STATIC
        elseif (intf.method == "dhcp") then
           if_cfg[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] = RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_DHCP
        elseif   (intf.method == "ppp") then
           if_cfg[RSM.RSM_TagID.TAG_NET_IF_ADDR_METHOD] = RSM.TAG_NET_IF_ADDR_METHOD_Types.TAG_NET_IF_ADDR_METHOD_PPP
        end
     end
     if intf.enabled then 
      local enabledString = "disabled"
      if (intf.enabled == "enabled") then
        enabledString = "enabled"
      end
        if_cfg[RSM.RSM_TagID.TAG_NET_PRIORITY] = enabledString
     end

     msg[if_ctr] = if_cfg
     if_ctr = if_ctr+1
  end
  return msg
end



 
