// A status page for the machine this runs on: CPU, memory, disks, network, load and processes,
// and a health check that says what is wrong. Numbers differ on every machine, so the routes
// here show that they make sense together.
//
//   quillo run system_info.qwe      then open http://localhost:8080/ and /health

use "system_info.qwer"

route GET / = system_info_summary()?

route GET /cpu {
    let c = system_info_cpu()?
    { has_brand: len(c.brand ?? "") > 0, logical_ok: c.logical >= 1, cores_match: len(c.per_core) == c.logical, usage_ok: c.usage_percent >= 0 && c.usage_percent <= 100, physical_ok: c.physical == null || c.physical <= c.logical, arch_ok: len(c.arch) > 0 }
}

route GET /memory {
    let m = system_info_memory()?
    { total_ok: m.total > 1048576, used_within: m.used <= m.total, percent_ok: m.used_percent > 0 && m.used_percent <= 100, gib_ok: m.total_gib > 0 }
}

route GET /disks {
    let all = system_info_disks({})?
    let real = system_info_disks({ real_only: true })?
    let here = system_info_disk_for(".")?
    { listed: len(all) >= 1, real_ok: len(real) >= 1 && len(real) <= len(all), sensible: len(real | filter((d) => d.available > d.total)) == 0, sorted: real[0].total >= real[len(real) - 1].total, here_ok: here.total > 0, no_path: system_info_disk_for("/no/such/path").error != null }
}

route GET /network {
    let first = system_info_network()?
    sleep(100)
    let second = system_info_network()?
    { interfaces: len(first) >= 1, named: len(first | filter((i) => len(i.name) == 0)) == 0, rates_later: len(second | filter((i) => i.rate_in == null)) == 0 }
}

route GET /load {
    let l = system_info_load()?
    let u = system_info_uptime()
    { load_ok: l.one >= 0, per_core_ok: l.per_core >= 0, up: u.seconds > 0, boot_ok: u.boot_time > 1000000000, text_ok: contains(u.text, ":") }
}

route GET /os {
    let o = system_info_os()
    { named: o.name != null, kernel: o.kernel != null, host: o.host != null }
}

route GET /processes {
    let top = system_info_processes({ sort: "memory", limit: 5 })?
    let me = system_info_self()?
    let found = system_info_processes({ name: "quillo", limit: 50 })?
    let counts = system_info_process_counts()?
    {
        five: len(top), sorted: top[0].memory >= top[4].memory, has_fields: top[0].pid > 0 && len(top[0].name) > 0,
        me_found: me.pid > 0 && contains(me.name, "quillo"), me_memory: me.memory > 0,
        by_name: len(found) >= 1,
        by_pid: system_info_process(me.pid)?.pid == me.pid,
        gone: system_info_process(4000000)?,
        counted: counts.total >= 5,
        bad_sort: system_info_processes({ sort: "age" }).error,
        bad_pid: system_info_process(-1).error,
    }
}

route GET /health {
    let calm = system_info_health({ memory_percent: 101, disk_percent: 101, load_per_core: 100000.0 })?
    let tight = system_info_health({ memory_percent: 0, disk_percent: 0 })?
    { calm: calm, warned: !tight.ok, says_memory: contains(tight.warnings[0], "memory is"), says_disk: len(tight.warnings) >= 2 && contains(tight.warnings[1], "% full") }
}
