-- glamkey_config.lua
--
-- Implements the web module to configure the GLAM key daemon configuration file.
--
require("luamods/layout")
require("luamods/command")
require("config/remote_access_conf")
local PropertyConfig = require("luamods/property_config")

--
-- Figure out user permission stuffies.
--
userLevel = db.getPriv(layout.username) or 1

if (userLevel == 1) then
    buttonControl = " disabled"
    inputControl = " readonly"
else
    buttonControl = ""
    inputControl = ""
end

-- Read config for key daemon into config management.
local properties = PropertyConfig.new(remote_access_conf.keyconfig_path)

if properties then
  -- Schedule restart of the key daemon for any changes to the config file.
  local function restartKeyDaemon()
    command.log('Restarting GLAM key daemon, config was changed.')
    command.ex(remote_access_conf.glamkeyd_restart)
  end
  properties:registerOnChangeAction(restartKeyDaemon)

  if (cgi.post["submitGlamButton"] ~= nil) and (userLevel ~= 1) then
    -- Apply changes to the properties table from cgi post.
    properties:applyIfDifferent({"glamkey", "server"}, cgi.post.glamkey_server_input)
    properties:applyIfDifferent({"server", "port"}, cgi.post.server_port_input)
    properties:applyIfDifferent({"glamkey", "lat"}, cgi.post.glamkey_lat_input)
    properties:applyIfDifferent({"glamkey", "serial"}, cgi.post.glamkey_serial_input)
    properties:applyIfDifferent({"glamkey", "lon"}, cgi.post.glamkey_lon_input)
    properties:applyIfDifferent({"glamkey", "port"}, cgi.post.glamkey_port_input)
    properties:applyIfDifferent({"glamkey", "box"}, cgi.post.glamkey_box_input)

    -- Write changes to config file and restart services if anything was updated.
    properties:saveIfChanged()
  end

  glamkey = {}
  server = {}
  -- The following entries should have some value.
  glamkey.server = properties:get({"glamkey", "server"}) or ""
  server.port = properties:get({"server", "port"}) or ""
  glamkey.port = properties:get({"glamkey", "port"}) or ""
  glamkey.box = properties:get({"glamkey", "box"}) or ""
  -- The next few entries must remain nil to indicate that no entry exists.
  glamkey.serial = properties:get({"glamkey", "serial"})
  glamkey.lat = properties:get({"glamkey", "lat"})
  glamkey.lon = properties:get({"glamkey", "lon"})
end

function generateContentWarning(headerText, messageText)
  return [[
    <div id="info">
      <center>
        <h2><img src="images/warning.png"/> ]]..headerText..[[</h2>
        ]]..messageText..[[
      </center>
    </div>
  ]]
end

--
-- Generate content for the final webpage.
--
function generateGlamKeyContent()
  -- Heading
  content = [[
    <div id="info">
      <div style="background-size:32px; background-repeat:no-repeat; background-position: 20px center;">
          <center><h1>GLAM Key Configuration</h1></center>
      </div>
    </div>
  ]]

  -- Check if the properties could be read from the config file.
  if not properties then
    content = content..generateContentWarning("Cannot read config file",
      [[The GLAM key configuration file "]]..remote_access_conf.keyconfig_path..[[" is missing or unreadable.]]
    )

    return content -- Return early, we can't show any more information.
  end

  local function genOneShotEditContent(keys)
    local elemContent = nil

    -- Unfortunately we have to build the name of the input elements dynamically.
    local inputName = table.concat(keys, "_").."_input"

    -- The content of the element is readonly if the config already exists in the config file.
    local configValue = PropertyConfig.derefTblElement(_G, keys)
    if configValue and configValue ~= "" then
      elemContent = [[<input type="text" name="]]..inputName..[[" value="]]..PropertyConfig.derefTblElement(_G, keys)..[[" readonly/>]]
    else
      elemContent = [[<input type="text" name="]]..inputName..[[" value=""]]..inputControl..[[/>]]
    end

    return elemContent
  end

  local glam_key_serial_content = genOneShotEditContent({"glamkey", "serial"})
  local glam_key_lat_content = genOneShotEditContent({"glamkey", "lat"})
  local glam_key_long_content = genOneShotEditContent({"glamkey", "lon"})

  -- We need some validation js. A simplifying assumption is that we can only change settings or add on "oneshot" if we
  -- have completed all configs (well if the user has).
  content=content..[[
    <script>
    var doValidate = 0;
     function validateForm(form)
     {
         if (form.getAttribute('submitted')) return false;

         if (!doValidate)
         {
             form.setAttribute('submitted', 'true');
             return true;
         }
         doValidate = 0;

         var inputs = form.getElementsByTagName("input");

         var inputIdx;
         var errors = 0;
         for (inputIdx = 0; inputIdx < inputs.length; inputIdx++)
         {
             // Don't validate buttons.
             if(inputs[inputIdx].type != "text")
               continue;

             var warning = document.getElementById("warning"+inputIdx);
             if (inputs[inputIdx].value == "")
             {
                 if (!warning)
                 {
                     warning = document.createElement("span");
                     warning.id = "warning"+inputIdx;
                     warning.innerHTML = " <img src='images/warning.png' alt='Cannot be blank' title='Cannot be blank'/>";
                     inputs[inputIdx].parentNode.appendChild(warning);
                 }
                 errors++;
             }
             else
             {
                 if (warning)
                 {
                     warning.parentNode.removeChild(warning);
                 }
             }
         }

         if (errors)
         {
             alert("Not all fields have been filled in.\nPlease enter/select valid values for the indicated fields.");
             return false;
         }
         else
         {
             form.setAttribute('submitted','true');
             return true;
         }
     }
    </script>
  ]]

  content = content..[[
    <div class="formLayoutfull">
      <form action="glamkey_config.lua" method="post" onsubmit="return validateForm(this)">
        <h3>GLAM Server</h3>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Address:</label>
          <input type="text" name="glamkey_server_input" value="]]..glamkey.server..[["]]..inputControl..[[/>
        </div>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Port:</label>
          <input type="text" name="glamkey_port_input" value="]]..glamkey.port..[["]]..inputControl..[[/>
        </div>
        <br><hr>
        <h3>GLAM Key</h3>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Serial:</label>
          ]]..glam_key_serial_content..[[
        </div>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Latitude:</label>
          ]]..glam_key_lat_content..[[
        </div>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Longitude:</label>
          ]]..glam_key_long_content..[[
        </div>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Port:</label>
          <input type="text" name="server_port_input" value="]]..server.port..[["]]..inputControl..[[/>
        </div>
        <div>
          <label style="width: 100px; display: inline-block; text-align: right;">Box:</label>
          <input type="text" name="glamkey_box_input" value="]]..glamkey.box..[["]]..inputControl..[[/>
        </div>
        <br><hr>
        <input type="submit" name="submitGlamButton" value="Save and Update"]]..buttonControl..[[/ onclick="doValidate = 1;">
  ]]

  if properties.hasChanged then
    content = content..[[
        <b><img src="images/ok.png"/> Changes saved.</b><br><br>
    ]]
  end

  content = content..[[
      </form>
      <script>
          function toggleVis(target)
          {
              if (target.style.display == "none")
              {
                  target.style.display = "inline-block";
              }
              else
              {
                  target.style.display = "none";
              }
              return false;
          }
      </script>
      <br><img src="images/magnify.png"/> <a href="javascript:void(0)" onclick="toggleVis(document.getElementById('glamKeyConfig'));">View ]]..remote_access_conf.keyconfig_path..[[</a></a><br>
      <div id="glamKeyConfig" style="display: none;">
        <pre class="formLayoutfull">]]..properties.configText..[[
        </pre>
      </div>
    </div>
  ]]

  return content
end -- generateGlamKeyContent

--
-- Generate the final webpage and send it along.
--
header = layout.getHeader()
content = generateGlamKeyContent()
footer = layout.getFooter()
print(header..content..footer)
