# Log fetch commands for the NATS admin bus.
#
# Fetches recent in-process log lines captured by the Rustelo `NatsLogLayer`
# tracing subscriber.  Lines are returned in chronological order.

use ./common.nu [build-admin-subject, nats-admin-request]

# Fetch recent log lines from the server's in-memory ring buffer.
#
# Returns a list of strings (one per log line) in chronological order.
#
# Examples:
#   nats-admin logs                        # last 100 lines
#   nats-admin logs --lines 50             # last 50 lines
#   nats-admin logs | where $it =~ "ERROR" # filter in-shell
export def "nats-admin logs" [
    --lines: int    = 100  # Number of recent lines to fetch (max 2000)
    --url:   string = ""   # NATS server URL override
    --creds: string = ""   # Credentials file override
] {
    let subject = build-admin-subject "admin.logs"
    let payload = { lines: $lines } | to json --raw

    nats-admin-request $subject $payload --url $url --creds $creds --timeout "10s"
        | from json
        | get lines
}

# Parse log lines into a table with level, target, and message columns.
#
# Line format produced by the Rust NatsLogLayer:
#   [LEVEL] target — message
#
# Examples:
#   nats-admin logs table
#   nats-admin logs table --lines 200 | where level == "ERROR"
export def "nats-admin logs table" [
    --lines: int    = 100
    --url:   string = ""
    --creds: string = ""
] {
    nats-admin logs --lines $lines --url $url --creds $creds
        | each { |line|
            let parts = $line | parse --regex '^\[(?P<level>\w+)\] (?P<target>[^ ]+) — (?P<message>.+)$'
            if ($parts | is-not-empty) {
                $parts | first
            } else {
                { level: "UNKNOWN", target: "", message: $line }
            }
        }
}

# Show only error and warning log lines.
#
# Examples:
#   nats-admin logs errors
#   nats-admin logs errors --lines 500
export def "nats-admin logs errors" [
    --lines: int    = 500
    --url:   string = ""
    --creds: string = ""
] {
    nats-admin logs --lines $lines --url $url --creds $creds
        | where { |line| ($line | str contains "[ERROR]") or ($line | str contains "[WARN]") }
}

# Poll logs repeatedly and print new lines since the last fetch.
#
# Runs until interrupted with Ctrl-C.
#
# Examples:
#   nats-admin logs tail
#   nats-admin logs tail --interval 3 --lines 30
export def "nats-admin logs tail" [
    --interval: int    = 5   # Poll interval in seconds
    --lines:    int    = 50  # Lines per fetch (keep small for tail use)
    --url:      string = ""
    --creds:    string = ""
] {
    mut last_seen: string = ""

    loop {
        let batch = nats-admin logs --lines $lines --url $url --creds $creds

        let new_lines = if ($last_seen | is-empty) {
            $batch
        } else {
            let pivot = $batch | enumerate | where { |it| $it.item == $last_seen } | last?
            if $pivot != null {
                $batch | skip ($pivot.index + 1)
            } else {
                $batch
            }
        }

        if ($new_lines | is-not-empty) {
            $new_lines | each { |line| print $line }
            $last_seen = ($new_lines | last)
        }

        sleep ($interval * 1sec)
    }
}
