#!/usr/bin/lua
--Function to execute terminal commands to run a separate program and returns value as string
local function exec(cmd)

  -- Starts program program in a separated process and returns a file handle 
  -- that you can use to read data from this program (if mode is "r", the default) 
  -- or to write data to this program (if mode is "w").
  local f = io.popen(cmd) 
  
  -- Reads the file, according to the given formats, which specify what to read. For each format, 
  -- the function returns a string (or a number) with the characters read, or nil if it cannot read 
  -- data with the specified format.
  -- "*n" reads a number; this is the only format that returns a number instead of a string.
  -- "*a" reads the whole file, starting at the current position. On end of file, it returns the empty string 
  -- "*|" reads the next line (skipping the end of line), returning nil on end of file. This is the default format.
  -- Number reads a string with up to this number of characters, returning nil on end of file. 
  -- If number is zero, it reads nothing and returns an empty string, or nil on end of file.
  local value = f:read("*a") or "none"
  
  -- Closes file. Note that files are automatically closed when their handles are garbage collected, but 
  -- that takes an unpredictable amount of time to happen.
  f:close()
  
  return value
end


function file_exists(name)

  -- This function opens a file, in the mode specified in the string mode. 
  -- It returns a new file handle, or, in case of errors, nil plus an error message. 
  -- The mode string can be any of the following: 
  -- "r":  read mode (the default);
  --  "w":  write mode;
  --  "a":  append mode;
  --  "r+": update mode, all previous data is preserved;
  --  "w+": update mode, all previous data is erased;
  --  "a+": append update mode, previous data is preserved, writing is only allowed at the end of file.
  -- The mode string can also have a ‘b‘ at the end, which is needed in some systems to open the file in binary mode. 
  -- This string is exactly what is used in the standard C function fopen.
   local f = io.open(name,"r")
   
   if f~=nil then 
   
   -- Equivalent to file:close(). Without a file, closes the default output file.
    io.close(f) 
    return true 
   else 
     return false 
   end
end


local function process_cfg(gnxid_output)
   local cfg = {}
 
   local lines = gnxid_output:gmatch("(GNX_%S+=%S+)\n")
   for line in lines do
        local key,value = line:match("(GNX_%S+)=(.+)")
        cfg[key] = value;
   end
   return cfg
end

local function do_hw_init(cfg,unit)
   if unit then
   print("Initialising unit "..unit)
   else
   print("Initialising All Hardware")
   end   
   for key,value in pairs(cfg) do
      local dev,owner,edit,baud,bits,stop,type = value:match("(.-):(.-):(.-):(.-):(.-):(.-):(.-)")
      if dev then
         local run_this = false

         if unit and unit == owner then
            run_this = file_exists([[/etc/hwinit/]]..owner)
         else if not unit then
            run_this = file_exists([[/etc/hwinit/]]..owner)
            end
         end   
         
         if run_this then
            print("Initialising "..owner)
            init_res = exec([[/bin/bash /etc/hwinit/]]..owner.." "..key.." "..dev.." "..owner.." "..edit.." "..baud.." "..bits.." "..stop.." "..type)
            print(init_res)
         end
      end
   end
end

local function do_enable_scripts(cfg)
   print("Enabling HW Scripts")
   for key,value in pairs(cfg) do
      local dev,owner,edit,baud,bits,stop,type = value:match("(.-):(.-):(.-):(.-):(.-):(.-):(.-)")
      if dev then
         if file_exists([[/usr/share/kses/hwinit/]]..owner) then
            print("Enabling "..owner)
            init_res = exec([[ln -sv /usr/share/kses/hwinit/]]..owner..[[ /etc/hwinit/]]..owner)
            print(init_res)
         end   
      end
   end
end


local function main()
   
   local gnxid_result = exec([[gnxid -l]])
   local cfg = process_cfg(gnxid_result)
   local cmd = "init"
   local unit = nil
   
   if arg[1] then cmd = arg[1] end
   
   if arg[2] then unit = arg[2] end
   
   if cmd == "init" then
      do_hw_init(cfg,unit)
   else if cmd == "enable" then
        do_enable_scripts(cfg) 
        end  
   end
   
end



main()
