-- FF_STORY_COMPUTER_GUARD
local function ff_story_computer_allowed()
  local label = os.getComputerLabel and os.getComputerLabel() or nil
  return fs.exists(".ff_story_computer")
    or fs.exists(".ff_titan_computer")
    or fs.exists(".ff_titan_program_id")
    or fs.exists(".ff_titan_allow_autoinstall")
    or fs.exists(".ff_titan_allow_autorun")
    or (label ~= nil and string.sub(string.lower(label), 1, 9) == "ff_titan:")
end

if not ff_story_computer_allowed() then
  return
end
-- TITAN GREEN SECTOR
-- SECURITY OFFICE TERMINAL
-- Save as: startup
--
-- Output stays ON after success.
-- Wire OUTPUT_SIDE into lower gate progress system or security door contraption.

local OUTPUT_SIDE = "back"
local STATE_FILE = ".green_black_clearance"

local answers = {
  tier = "BLACK",
  camera = "MIRROR",
  cell = "THIRTEEN",
  issue = "ISSUE"
}

local function hasColor()
  return term.isColor and term.isColor()
end

local function c(col)
  if hasColor() then term.setTextColor(col) end
end

local function cls()
  term.setBackgroundColor(colors.black)
  term.clear()
  term.setCursorPos(1, 1)
end

local function writeLine(text, col)
  c(col or colors.white)
  print(text)
end

local function readClean()
  c(colors.white)
  write("> ")
  local s = read() or ""
  s = string.upper(s)
  s = string.gsub(s, "^%s+", "")
  s = string.gsub(s, "%s+$", "")
  return s
end

local function pause()
  c(colors.gray)
  print("")
  print("[key] back")
  os.pullEvent("key")
end

local function header(title)
  cls()
  c(colors.cyan)
  print("GREEN SECURITY OFFICE")
  c(colors.gray)
  print("LOCAL SECURITY TERMINAL")
  print("---------------------------------------")
  if title then
    c(colors.white)
    print(title)
    c(colors.gray)
    print("---------------------------------------")
  end
  c(colors.white)
end

local function complete()
  return fs.exists(STATE_FILE)
end

local function saveComplete()
  local f = fs.open(STATE_FILE, "w")
  f.write("BLACK CLEARANCE")
  f.close()
end

local function setOutput(on)
  redstone.setOutput(OUTPUT_SIDE, on)
end

local function bootRedstone()
  setOutput(complete())
end

local function draw(lines)
  for _, line in ipairs(lines) do
    if line == "BLACK" or line == "MIRROR" or line == "THIRTEEN" or line == "ISSUE" then
      writeLine(line, colors.lime)
    elseif string.find(line, "WRONG") or string.find(line, "FAILED") or string.find(line, "missing") then
      writeLine(line, colors.red)
    elseif string.find(line, "SECURITY") or string.find(line, "BADGE") or string.find(line, "LOCK") then
      writeLine(line, colors.cyan)
    elseif string.find(line, "cell") or string.find(line, "camera") or string.find(line, "holding") then
      writeLine(line, colors.orange)
    else
      writeLine(line, colors.white)
    end
  end
end

local function page(title, lines)
  header(title)
  draw(lines)
  pause()
end

local function status()
  if complete() then
    page("STATUS", {
      "BLACK CLEARANCE: ISSUED",
      "",
      "Output is ON.",
      "",
      "Lower hull access panel may now",
      "accept the security requirement.",
      "",
      "This terminal has not contacted",
      "the main Titan database."
    })
  else
    page("STATUS", {
      "BLACK CLEARANCE: LOCKED",
      "",
      "Security office is local only.",
      "",
      "Find four file words.",
      "",
      "The card printer is offline.",
      "This terminal can still authorize",
      "the lower access board."
    })
  end
end

local function fileTier()
  page("FILE: CLEARANCE TIER", {
    "BADGE MEMO",
    "",
    "Lower hull never accepted red cards.",
    "",
    "Required tier word:",
    "",
    "BLACK",
    "",
    "Do not print it on the card face.",
    "Someone did.",
    "",
    "Didn't that card go missing?"
  })
end

local function fileCamera()
  page("FILE: SURVEILLANCE", {
    "CAMERA 12",
    "",
    "Office feed shows the office feed.",
    "I swear that mirror should be inverted.",   
    "",
    "MIRROR",
    "",
    "Security covered it with tape."
  })
end

local function fileCell()
  page("FILE: HOLDING CELLS", {
    "HOLDING LOG",
    "",
    "Cell 13 is not on the visitor map.",
    "",
    "It is on the cleaning schedule.",
    "",
    "Authorization word:",
    "",
    "THIRTEEN",
  })
end

local function fileIssue()
  page("FILE: BADGE PRINTER", {
    "CARD PRINTER NOTE",
    "",
    "Printer jammed during lockdown.",
    "Physical card can not be produced.",
    "",
    "Stamp word:",
    "",
    "ISSUE",
    "",
    "This authorizes the route board!"
  })
end

local function fileArmory()
  page("FILE: ARMORY", {
    "ARMORY NOTE",
    "",
    "Do not open during quarantine.",
    "",
    "Engineering asked who sealed",
    "the only working respirators."
  })
end

local function fileOffice()
  page("FILE: OFFICE AUDIO", {
    "AUDIO CLIP",
    "",
    "Guard says:",
    "\"I can see myself on camera.\"",
    "",
    "Second voice says:",
    "\"Wave.\"",
    "",
    "Guard does not wave.",
    "",
    "Camera shows him waving.",
    "Someone is fooling with me.",
    "Am I going crazy?"
  })
end

local function fileMissing()
  page("FILE: MISSING CARD", {
    "BLACK CARD SEARCH",
    "",
    "Last seen in security office.",
    "",
    "Then seen in elevator cage.",
    "",
    "Same timestamp???",
    "",
    "Card reader accepted all two.",
    "Card removed from trust list."
  })
end

local function fail(label, got)
  page("FAILED", {
    "CHECK FAILED",
    "",
    "Field:",
    label,
    "",
    "Input:",
    got,
    "",
    "Result:",
    "WRONG",
    "",
    "Read the matching file.",
    "The answer is one word."
  })
end

local function ask(label, expected)
  header("AUTH / " .. label)
  draw({
    "Enter one word.",
    "",
    "Field:",
    label,
    ""
  })

  local got = readClean()

  if got == expected then
    c(colors.lime)
    print("")
    print("CORRECT")
    sleep(0.7)
    return true
  end

  c(colors.red)
  print("")
  print("INCORRECT")
  sleep(0.7)
  fail(label, got)
  return false
end

local function auth()
  if complete() then
    page("AUTH", {
      "Already issued.",
      "",
      "Output remains ON."
    })
    return
  end

  if not ask("TIER", answers.tier) then return end
  if not ask("CAMERA", answers.camera) then return end
  if not ask("CELL", answers.cell) then return end
  if not ask("CARD", answers.issue) then return end

  saveComplete()
  setOutput(true)

  page("AUTHORIZED", {
    "ALL WORDS ACCEPTED",
    "",
    "Tier file: OK",
    "Camera file: OK",
    "Cell file: OK",
    "Card file: OK",
    "",
    "BLACK CLEARANCE ISSUED",
    "",
    "Output is now held ON."
  })
end

bootRedstone()

while true do
  header()

  if complete() then
    writeLine("BLACK CLEARANCE: ISSUED", colors.lime)
  else
    writeLine("BLACK CLEARANCE: LOCKED", colors.red)
  end

  print("")
  writeLine("1. Status")
  writeLine("2. Clearance tier")
  writeLine("3. Surveillance file")
  writeLine("4. Holding cells")
  writeLine("5. Badge printer")
  writeLine("6. Armory note")
  writeLine("7. Office audio")
  writeLine("8. Missing card")
  writeLine("A. AUTH")
  writeLine("Q. Close")
  print("")

  local input = readClean()

  if input == "Q" or input == "QUIT" or input == "EXIT" then
    cls()
    writeLine("SESSION CLOSED", colors.gray)
    return
  elseif input == "1" then
    status()
  elseif input == "2" then
    fileTier()
  elseif input == "3" then
    fileCamera()
  elseif input == "4" then
    fileCell()
  elseif input == "5" then
    fileIssue()
  elseif input == "6" then
    fileArmory()
  elseif input == "7" then
    fileOffice()
  elseif input == "8" then
    fileMissing()
  elseif input == "A" or input == "AUTH" then
    auth()
  else
    c(colors.red)
    print("Invalid.")
    sleep(0.7)
  end
end