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

local P = {};
P.__index = P;

local configFile = "/etc/rsm/coollogic/coollogicconfig.xml"

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


local function log(msg)
    command_exec("logger -t coollogic "..msg)
end

local function getCoolLogicConfig()
  local xml = command_exec("cat "..configFile)
  
  local coolConfig = {}
  coolConfig.rotation = xml:match("<airconRotation>%s*(.-)%s*</airconRotation>")
  coolConfig.freeAir = xml:match("<useFreeAir>%s*(.-)%s*</useFreeAir>")
  coolConfig.hiTemp = xml:match("<useFanInHiTemp>%s*(.-)%s*</useFanInHiTemp>")
  coolConfig.goal = xml:match("<goalTemperature>%s*(.-)%s*</goalTemperature>")
  coolConfig.internal = xml:match("<internalProbeLabel>%s*(.-)%s*</internalProbeLabel>")
  coolConfig.external = xml:match("<externalProbeLabel>%s*(.-)%s*</externalProbeLabel>")
  
  local index = 0;
  coolConfig.aircons = {}    
  for number,label in xml:gmatch("<aircon>.-<number>%s-(.-)%s-</number>.-<label>%s-(.-)%s-</label>.-</aircon>") do  
    coolConfig.aircons[index] = {}
    coolConfig.aircons[index].label = label
    coolConfig.aircons[index].number = number
    index = index + 1
  end
  
  index = 0;
  coolConfig.fans = {}
  for label in xml:gmatch("<fan>.-<label>%s-(.-)%s-</label>.-</fan>") do
    coolConfig.fans[index] = {}
    coolConfig.fans[index].label = label
    index = index + 1
  end
  
  return coolConfig          
end


local function printConfig(coolConfig)  
  log("rotation: "..coolConfig.rotation);
  log("freeAir : "..coolConfig.freeAir);
  log("hiTemp  : "..coolConfig.hiTemp);
  log("goal    : "..coolConfig.goal);
  log("internal: "..coolConfig.internal);
  log("external: "..coolConfig.external);
  
  for number, aircon in pairs(coolConfig.aircons) do
    log("AIR["..number.."] "..aircon.label)
  end
  
  for number, fan in pairs(coolConfig.fans) do
    log("FAN["..number.."] "..fan.label)
  end
end


local function getObject(key, value)
  local profile_cfg = {}
  profile_cfg.objid =  RSM.RSM_TagID.TAG_METALIST
  profile_cfg[RSM.RSM_TagID.TAG_METALIST_NAME] = "coollogic"
  profile_cfg[RSM.RSM_TagID.TAG_CAP_LABEL] = key
  profile_cfg[RSM.RSM_TagID.TAG_CAP_VALUE] = value 
  return profile_cfg
end

local function config_to_msg(coolConfig)
  local msg = {}
  local index = 0;

  msg[index] = getObject("rotation", coolConfig.rotation)  
  index = index + 1
  msg[index] = getObject("freeAir", coolConfig.freeAir)  
  index = index + 1
  msg[index] = getObject("hiTemp", coolConfig.hiTemp)  
  index = index + 1
  msg[index] = getObject("goal", coolConfig.goal)  
  index = index + 1
  msg[index] = getObject("internal", coolConfig.internal)  
  index = index + 1
  msg[index] = getObject("external", coolConfig.external)  
  index = index + 1
  if coolConfig.aircons and coolConfig.aircons[0] then
    msg[index] = getObject("air1", coolConfig.aircons[0].label)
    index = index + 1
  end
  if coolConfig.aircons and coolConfig.aircons[1] then
    msg[index] = getObject("air2", coolConfig.aircons[1].label)
    index = index + 1
  end

  if coolConfig.fans and coolConfig.fans[0] then
    msg[index] = getObject("fan", coolConfig.fans[0].label)
    index = index + 1
  end

  return msg
end

--Convert the config file into an object message and return that.
function P.getConfig()
  local coolConfig = getCoolLogicConfig() 
  printConfig(coolConfig)
  return config_to_msg(coolConfig)
end

local function writeFile(fileName, value)
  if fileName == null then
    log("fail")
    return false
  end

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

local function updateProfile(coolConfig)
  if coolConfig == null then
    return
  end
  
  local xml = [[
<?xml version="1.0"?>
<config>
]]
  if coolConfig.rotation then
    xml = xml..[[    <airconRotation>]]..coolConfig.rotation..[[</airconRotation>
]]
  end
  if coolConfig.freeAir then
    xml = xml..[[    <useFreeAir>]]..coolConfig.freeAir..[[</useFreeAir>
]]
  end 
  if coolConfig.hiTemp then
    xml = xml..[[    <useFanInHiTemp>]]..coolConfig.hiTemp..[[</useFanInHiTemp>
]]
  end
  if coolConfig.goal then
    xml = xml..[[    <goalTemperature>]]..coolConfig.goal..[[</goalTemperature>
]]
  end
  if coolConfig.internal then
    xml = xml..[[    <internalProbeLabel>]]..coolConfig.internal..[[</internalProbeLabel>
]]
  end
  if coolConfig.external then
    xml = xml..[[    <externalProbeLabel>]]..coolConfig.external..[[</externalProbeLabel>
]]
  end
  if coolConfig.aircons then
    for number, aircon in pairs(coolConfig.aircons) do
      xml = xml..[[    <aircon>
]]
      xml = xml..[[        <number>]]..aircon.number..[[</number>
]]
      xml = xml..[[        <label>]]..aircon.label..[[</label>
    </aircon>
]]
    end
  end
  if coolConfig.fans then
    for number, fan in pairs(coolConfig.fans) do
      xml = xml..[[    <fan>
]]
      xml = xml..[[        <label>]]..fan.label..[[</label>
    </fan>
]]
    end
  end

 
 xml = xml..[[
</config>
]]
 
 writeFile(configFile, xml)
end

local function updateKeyValue(key, value, coolConfig)
  
  log("set msg: "..key.." "..value)
  
  if key == "rotation" then
    coolConfig.rotation = value
    return coolConfig
  end
  if key == "freeAir" then
    coolConfig.freeAir = value
    return coolConfig
  end
  if key == "goal" then
    coolConfig.goal = value
    return coolConfig
  end
  if key == "hiTemp" then
    coolConfig.hiTemp = value
    return coolConfig
  end
  if key == "internal" then
    coolConfig.internal = value
    return coolConfig
  end
  if key == "external" then
    coolConfig.rotation = value
    return coolConfig
  end
  if key == "air1" then
    coolConfig.aircons[0].label = value
    return coolConfig
  end
  if key == "air2" then
    coolConfig.aircons[1].label = value
    return coolConfig
  end
  if key == "fan" then
    coolConfig.fans[0].label = value
    return coolConfig
  end
  
  return coolConfig
end

local function updateConfig(msg)
  local coolConfig = getCoolLogicConfig()
  
  for id, obj in pairs(msg) do
    if obj.objid == RSM.RSM_TagID.TAG_METALIST then
      if obj[RSM.RSM_TagID.TAG_METALIST_NAME] == "coollogic" then
        if obj[RSM.RSM_TagID.TAG_CAP_LABEL] and obj[RSM.RSM_TagID.TAG_CAP_VALUE] then
          coolConfig = updateKeyValue(obj[RSM.RSM_TagID.TAG_CAP_LABEL], obj[RSM.RSM_TagID.TAG_CAP_VALUE], coolConfig)
        end      
      end
    end
  end
  
  return coolConfig
end

function P.setConfig(msg)  
  local coolConfig = updateConfig(msg) 
  updateProfile(coolConfig)
end

function P.deleteConfig(cfg)
end

function P.replaceConfig(cfg) 
end


P.__tostring = function () return "Coollogic package"; end

local coollogic = {};
setmetatable(coollogic, P);
return coollogic;
