#!/usr/bin/lua

local type_id = 64 -- bat-hosts

function get_hostname()
  local hostfile = io.open("/proc/sys/kernel/hostname", "r")
  local ret_string = hostfile:read()
  hostfile:close()
  return ret_string
end

function get_interfaces_names()
  local ret = {}

  for name in io.popen("ls -1 /sys/class/net/"):lines() do
    table.insert(ret, name)
  end

  return ret
end

function get_interface_address(name)
  local addressfile = io.open("/sys/class/net/"..name.."/address", "r")
  local ret_string = addressfile:read()
  addressfile:close()
  return ret_string
end


local function generate_bat_hosts()
-- get hostname and interface macs/names
-- then return a table containing valid bat-hosts lines
  local n, i
  local ifaces, ret = {}, {}

  local hostname = get_hostname()

  for n, i in ipairs(get_interfaces_names()) do
    local address = get_interface_address(i)
    if not ifaces[address] then ifaces[address] = i end
  end

  for mac, iname in pairs(ifaces) do
    if mac:match("^%x%x:%x%x:%x%x:%x%x:%x%x:%x%x$") and not mac:match("00:00:00:00:00:00") then
      table.insert(ret, mac.." "..hostname.."_"..iname.."\n")
    end
  end

  return ret
end

local function publish_bat_hosts()
-- pass a raw chunk of data to alfred
  local fd = io.popen("alfred -s " .. type_id, "w")
  if fd then
    local ret = generate_bat_hosts()
    if ret then
      fd:write(table.concat(ret))
    end
    fd:close()
  end
end

local function write_bat_hosts(rows)
  local content = { "### /tmp/bat-hosts generated by alfred-bat-hosts\n",
                    "### /!\\ This file is overwritten every 5 minutes /!\\\n",
                    "### (To keep manual changes, replace /etc/bat-hosts symlink with a static file)\n" }

  -- merge the chunks from all nodes, de-escaping newlines
  for _, row in ipairs(rows) do
    local node, value = unpack(row)
    table.insert(content, "# Node ".. node .. "\n")
    table.insert(content, value:gsub("\x0a", "\n") .. "\n")
  end

  -- write parsed content down to disk
  local fd = io.open("/tmp/bat-hosts", "w")
  if fd then
    fd:write(table.concat(content))
    fd:close()
  end

  -- try to make a symlink in /etc pointing to /tmp,
  -- if it exists, ln will do nothing.
  os.execute("ln -ns /tmp/bat-hosts /etc/bat-hosts 2>/dev/null")
end

local function receive_bat_hosts()
-- read raw chunks from alfred, convert them to a nested table and call write_bat_hosts
-- "alfred -r" can fail in slave nodes (returns empty stdout), so:
-- check output is not null before writing /tmp/bat-hosts, and retry 3 times before giving up.
  for n = 1, 3 do
    local fd = io.popen("alfred -r " .. type_id)
      --[[ this command returns something like
      { "54:e6:fc:b9:cb:37", "00:11:22:33:44:55 ham_wlan0\x0a00:22:33:22:33:22 ham_eth0\x0a" },
      { "90:f6:52:bb:ec:57", "00:22:33:22:33:23 spam\x0a" },
      ]]--

    if fd then
      local output = fd:read("*a")
      fd:close()
      if output and output ~= "" then
        assert(loadstring("rows = {" .. output .. "}"))()
        write_bat_hosts(rows)
        break
      end
    end
  end
end

publish_bat_hosts()
receive_bat_hosts()
