-- Mekanism Fission Reactor Monitor for CC:Tweaked
-- Monitoring only: this program does NOT control or safety-shut down the reactor.

local reactor, reactorName
for _, name in ipairs(peripheral.getNames()) do
    local ok, types = pcall(peripheral.getType, name)
    if ok then
        local typeText = type(types) == "table" and table.concat(types, " ") or tostring(types)
        if typeText:lower():find("fissionreactorlogicadapter", 1, true) then
            reactorName = name
            reactor = peripheral.wrap(name)
            break
        end
    end
end

if not reactor then
    term.clear()
    term.setCursorPos(1, 1)
    print("FISSION REACTOR MONITOR")
    print("")
    print("No Fission Reactor Logic Adapter found.")
    print("Check the wired modem network.")
    print("")
    print("Peripherals found:")
    for _, name in ipairs(peripheral.getNames()) do print("- " .. name) end
    return
end

local monitor = peripheral.find("monitor")
local screen = monitor or term
if monitor then pcall(monitor.setTextScale, 0.5) end

local wanted = {
    "status", "formed", "temperature", "damage", "fuel",
    "waste", "coolant", "water", "steam", "burn",
    "heating", "heated", "cooled", "energy", "capacity",
    "boil", "depletion", "reactor"
}

local function matches(name)
    local s = name:lower()
    for _, word in ipairs(wanted) do
        if s:find(word, 1, true) then return true end
    end
    return false
end

local function prettyName(s)
    s = s:gsub("^get", ""):gsub("^is", ""):gsub("^has", "")
    s = s:gsub("([a-z])([A-Z])", "%1 %2")
    return s
end

local function stringify(value)
    if type(value) == "boolean" then return value and "YES" or "NO" end
    if type(value) == "number" then
        return string.format("%.2f", value)
    end
    if type(value) == "table" then
        local ok, result = pcall(textutils.serialize, value)
        if ok then return result end
    end
    return tostring(value)
end

local function readMethod(method)
    local ok, value = pcall(reactor[method])
    if ok and value ~= nil then return stringify(value) end
    return nil
end

while true do
    local width, height = screen.getSize()
    screen.setBackgroundColor(colors.black)
    screen.setTextColor(colors.white)
    screen.clear()

    local y = 1
    local function line(text, color)
        if y <= height then
            screen.setCursorPos(1, y)
            screen.setTextColor(color or colors.white)
            screen.clearLine()
            screen.write(tostring(text):sub(1, width))
            y = y + 1
        end
    end

    line("== FISSION REACTOR MONITOR ==", colors.cyan)
    line("Peripheral: " .. reactorName, colors.gray)
    line(string.rep("-", math.min(width, 30)), colors.gray)

    local okMethods, methods = pcall(peripheral.getMethods, reactorName)
    local shown = 0
    if okMethods and type(methods) == "table" then
        table.sort(methods)
        for _, method in ipairs(methods) do
            if matches(method) then
                local value = readMethod(method)
                if value ~= nil then
                    local label = prettyName(method)
                    line(label .. ": " .. value, colors.white)
                    shown = shown + 1
                end
            end
        end
    end

    if shown == 0 then
        line("No readable stats found.", colors.orange)
        line("Check adapter methods/version.", colors.orange)
    end

    line(string.rep("-", math.min(width, 30)), colors.gray)
    line("Refresh: every 2 seconds", colors.lime)
    line("Monitor only - not a safety system", colors.red)
    sleep(2)
end