local URL_ERROR = "http://cloud.fse-media.group/d/API/TicketMachine/error.dfpwm?sign=DvQ39wQDN6Cej4KPhAkM3JyXPM466koan6w9CckPxWU=:0"
local URL_PASS = "http://cloud.fse-media.group/d/API/TicketMachine/pass.dfpwm?sign=ZJfGDYnaxQU4JrGSh4NDzKZtjq3eMjYh9KHmMSAMKZA=:0"
local URL_GATE = "http://cloud.fse-media.group/d/API/TicketMachine/gate.lua?sign=OWy1wKkKhUhpnxXKeX6fRLePSg1XcaQgWOLvQbMuHRQ=:0"

local CONFIG_PATH = "gate_config.json"

local function trim(s)
  return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end

local function splitCsv(s)
  local out = {}
  s = trim(s)
  if #s == 0 then return out end
  for part in s:gmatch("[^,/%s]+") do
    local v = trim(part)
    if #v > 0 then table.insert(out, v) end
  end
  return out
end

local function writeFile(path, content, binary)
  local mode = binary and "wb" or "w"
  local f = fs.open(path, mode)
  if not f then return false end
  f.write(content)
  f.close()
  return true
end

local function prompt(label)
  term.write(label)
  return trim(read() or "")
end

local function promptOptionalUrl(label)
  local raw = prompt(label)
  raw = trim(raw)
  if #raw == 0 then return nil end
  return raw
end

local function httpGet(url)
  if not http then return false, "HTTP API disabled" end
  local okReq, err = pcall(function()
    http.request({ url = url, method = "GET" })
  end)
  if not okReq then return false, tostring(err) end

  while true do
    local ev, p1, p2, p3 = os.pullEvent()
    if ev == "http_success" and p1 == url then
      local res = p2
      if type(res) == "table" and type(res.readAll) == "function" then
        local data = res.readAll()
        res.close()
        return true, data
      end
      return false, "invalid http response"
    end
    if ev == "http_failure" and p1 == url then
      local err = p2
      local res = p3
      if type(p2) == "table" and type(p2.readAll) == "function" then
        res = p2
        err = p3
      end
      if type(res) == "table" and type(res.readAll) == "function" then
        local data = res.readAll()
        res.close()
        return false, data
      end
      return false, tostring(err or "http_failure")
    end
  end
end

local function download(url, path, binary)
  print("Downloading: " .. path)
  local ok, data = httpGet(url)
  if not ok then
    print("Download failed: " .. tostring(data or ""))
    return false
  end
  if not writeFile(path, data, binary) then
    print("Write failed: " .. path)
    return false
  end
  return true
end

local function normalizeMode(raw)
  return (trim(raw):lower() == "exit") and "exit" or "entry"
end

term.clear()
term.setCursorPos(1, 1)
print("Bidirectional Ticket Gate Installer")
print("")

local stationsRaw = prompt("Station codes (comma or slash): ")
local stationCodes = splitCsv(stationsRaw)
if #stationCodes == 0 then
  print("No station codes provided.")
  return
end

print("")
print("Set mode for each side (front/back).")
local frontRaw = prompt("Front mode (entry/exit): ")
local backRaw = prompt("Back mode (entry/exit): ")
local frontMode = normalizeMode(frontRaw)
local backMode = normalizeMode(backRaw)
local frontStationCode = trim(prompt("Front station code (default first code): "))
local backStationCode = trim(prompt("Back station code (default first code): "))
if #frontStationCode == 0 then frontStationCode = stationCodes[1] end
if #backStationCode == 0 then backStationCode = stationCodes[1] end

print("")
print("Optional server config for ticket / IC card checks.")
local ticketServerUrl = promptOptionalUrl("Ticket check URL (blank=auto): ")
local cardServerUrl = promptOptionalUrl("IC card check URL (blank=same server): ")

local cfg = {
  station_codes = stationCodes,
  station_code = stationCodes[1],
  side_modes = {
    front = frontMode,
    back = backMode,
  },
  side_station_codes = {
    front = frontStationCode,
    back = backStationCode,
  }
}
if ticketServerUrl then cfg.server_url = ticketServerUrl end
if cardServerUrl then cfg.card_server_url = cardServerUrl end
local okCfg, cfgJson = pcall(textutils.serializeJSON, cfg)
if not okCfg then
  print("Config serialize failed.")
  return
end
if not writeFile(CONFIG_PATH, cfgJson, false) then
  print("Failed to write config.")
  return
end

if not download(URL_PASS, "pass.dfpwm", true) then return end
if not download(URL_ERROR, "error.dfpwm", true) then return end

local okGate, gateCode = httpGet(URL_GATE)
if not okGate then
  print("Download failed: startup")
  return
end

writeFile("startup.lua", gateCode, false)
writeFile("startup", gateCode, false)

print("")
print("Done.")
print("This gate now supports tickets and IC cards.")
print("Attach ticket_inspection_machine on FRONT and BACK.")
print("Reboot the computer to start the gate.")
