--[[
  @package eg4-crank-ui-2
  @file    network-connections.lua
  @brief   Handles the network connections settings.
]]


--- Local cache for settings
local settings

---
--- @brief  Initialises the network connections screen.
--- @param  gre#context mapargs
function cb_init_network_connections(mapargs)
  settings = {}
  local control = get_list_control(mapargs.context_screen)
  local connections = sbsettings.read_g4_network_connections()
  local index = 0
  local data = {}
  for _,port_id in ipairs(connections) do
    index = index + 1
    data[string.format(control..".port_id.%d.1", index)] = port_id
    data[string.format(control..".text.%d.1", index)] = port_id
    data[string.format(control..".value.%d.1", index)] = sbsettings.get_network_port_connection_linked_protocol(port_id)
    data[string.format(control..".alpha_pressed.%d.1", index)] = 0
  end
  gre.set_data(data)
  local height = gre.get_table_cell_attrs(control, 1, 1, "height").height
  gre.set_table_attrs(control, { height = index * height, rows = index })
  cb_update_menu(mapargs)
end

---
--- @brief  Creates a port id string from the given port id.
--- @param  port_id
--- @return port id string
local function make_port_id(port_id)
  local transport = get_network_connection_transport(port_id)
  local port_no = get_network_connection_port_no(port_id)
  local mode = get_network_connection_mode(port_id)
  local domain = get_network_connection_domain(port_id)
  return string.format("%s://%s:%s", transport == 0 and "udp" or "tcp", mode == 0 and "@" or domain, port_no)
end

---
--- @brief  Writes the network connection settings to the given port id.
--- @param  port_id
local function write_network_connection(port_id)
  local port_id = settings.port_id or port_id
  local url = make_port_id(port_id)

  if port_id ~= "" and port_id ~= url then
    sbsettings.set_network_port_connection_linked_protocol("-", port_id)
  end

  local domain = url:match(".-://(.-):") or ""
  if domain ~= "" then 
    local linked_protocol = get_network_connection_linked_protocol(port_id)
    sbsettings.set_network_port_connection_linked_protocol(linked_protocol, url)
    settings.port_id = url
  end
end

---
--- @brief  Gets the linked protocol for the given port id.
--- @param  port_id
--- @return linked protocol
function get_network_connection_linked_protocol(port_id)
  if not settings.protocol then
    settings.protocol = sbsettings.get_network_port_connection_linked_protocol(port_id) or "-"
  end
  return settings.protocol
end

---
--- @brief  Sets the linked protocol for the given port id.
--- @param  value linked protocol
--- @param  port_id
function set_network_connection_linked_protocol(value, port_id)
  settings.protocol = value
  write_network_connection(port_id)
end

---
--- @brief  Gets the transport type for the given port id.
--- @param  port_id
--- @return transport type
function get_network_connection_transport(port_id)
  if not settings.transport then
    settings.transport = port_id:starts_with("tcp://") and 1 or 0
  end
  return settings.transport
end

---
--- @brief  Sets the transport type for the given port id.
--- @param  value transport type
--- @param  port_id
function set_network_connection_transport(value, port_id)
  settings.transport = value
  write_network_connection(port_id)
end

---
--- @brief  Gets the port number for the given port id.
--- @param  port_id
--- @return port number
function get_network_connection_port_no(port_id)
  if not settings.port_no then
    local port_no = port_id:match(".-://.-:(%d+)")
    settings.port_no = port_no or "0"
  end
  return settings.port_no
end

---
--- @brief  Sets the port number for the given port id.
--- @param  value port number
--- @param  port_id
function set_network_connection_port_no(value, port_id)
  settings.port_no = value
  write_network_connection(port_id)
end

---
--- @brief  Gets the connection mode for the given port id.
--- @param  port_id
--- @return 0 server, 1 client
function get_network_connection_mode(port_id)
  if not settings.mode then
    if port_id == "" then
      settings.mode = 0
    else
      local domain = port_id:match(".-://(.-):") or ""
      settings.mode = domain == "@" and 0 or 1
    end
  end
  return settings.mode
end

---
--- @brief  Sets the connection mode for the given port id.
--- @param  value - 0 server, 1 client
--- @param  port_id
function set_network_connection_mode(value, port_id)
  settings.mode = value
  write_network_connection(port_id)
end

---
--- @brief  Gets the domain for the given port id.
--- @param  port_id
--- @return domain or ip address
function get_network_connection_domain(port_id)
  if not settings.domain then
    local domain = port_id:match(".-://(.-):") or ""
    if domain == "@" then domain = "" end
    settings.domain = domain or ""
  end
  return settings.domain
end

---
--- @brief  Sets the domain for the given port id.
--- @param  value domain or ip address
--- @param  port_id
function set_network_connection_domain(value, port_id)
  settings.domain = value
  write_network_connection(port_id)
end

---
--- @brief  Callback to handle the setting of the network connection domain or ip address.
--- @param  value domain or ip address
--- @param  port_id
function cb_set_network_connection_domain(value, port_id)
  set_network_connection_domain(value, port_id)
  cb_back_screen()
  return true
end

---
--- @brief  Callback to set the port number for the given port id.
--- @param  value port number
--- @param  port_id
--- @return true value is valid
function cb_set_network_connection_port_no(value, port_id)
  if not cb_port_number_validate(value) then return end
  set_network_connection_port_no(value, port_id)
  cb_back_screen()
  return true
end

---
--- @brief  Start the linked protocol selection screen
--- @param  gre#context mapargs
function cb_start_network_linked_protocol_selection(mapargs)
  local port_id = make_port_id(settings.port_id or mapargs.port_id)
  local init = {
    parameter = "network_connection_linked_protocol",
    as_value = 1,
    value = value,
    heading = port_id,
    list = sbsettings.read_available_g4_protocols(),
    port_id = port_id,
    event = "settings_updated",
  }
  start_radio_select(init)
end
