// healthcheck is a static binary used by Docker HEALTHCHECK CMD in distroless
// images (which have no shell, wget, or curl).
//
// Two modes:
//
//  1. HTTP mode (default):
//     /healthcheck <url>
//     Performs GET <url>; exits 0 if HTTP 2xx/3xx, 1 otherwise.
//     Example: /healthcheck http://localhost:8080/health
//
//  2. File-liveness mode:
//     /healthcheck file <path> <max_age_seconds>
//     Reads <path>, parses its content as RFC3339 timestamp, and exits 1 if the
//     timestamp is older than <max_age_seconds>. Used by the runner service which
//     writes /tmp/runner.alive on every successful poll.
//     Example: /healthcheck file /tmp/runner.alive 120
package main

import (
	"fmt"
	"net/http"
	"os"
	"strconv"
	"time"
)

func main() {
	if len(os.Args) > 1 && os.Args[1] == "file" {
		checkFile()
		return
	}
	checkHTTP()
}

// checkHTTP performs a GET request and exits 0 on success, 1 on failure.
func checkHTTP() {
	url := "http://localhost:8080/health"
	if len(os.Args) > 1 {
		url = os.Args[1]
	}
	resp, err := http.Get(url) //nolint:gosec,noctx
	if err != nil {
		fmt.Fprintf(os.Stderr, "healthcheck: %v\n", err)
		os.Exit(1)
	}
	resp.Body.Close()
	if resp.StatusCode >= 400 {
		fmt.Fprintf(os.Stderr, "healthcheck: status %d\n", resp.StatusCode)
		os.Exit(1)
	}
}

// checkFile reads a timestamp from a file and exits 1 if it is older than the
// given max age. Usage: /healthcheck file <path> <max_age_seconds>
func checkFile() {
	if len(os.Args) < 4 {
		fmt.Fprintln(os.Stderr, "healthcheck file: usage: /healthcheck file <path> <max_age_seconds>")
		os.Exit(1)
	}
	path := os.Args[2]
	maxAgeSec, err := strconv.ParseInt(os.Args[3], 10, 64)
	if err != nil {
		fmt.Fprintf(os.Stderr, "healthcheck file: invalid max_age_seconds %q: %v\n", os.Args[3], err)
		os.Exit(1)
	}

	data, err := os.ReadFile(path)
	if err != nil {
		fmt.Fprintf(os.Stderr, "healthcheck file: cannot read %s: %v\n", path, err)
		os.Exit(1)
	}

	ts, err := time.Parse(time.RFC3339, string(data))
	if err != nil {
		// Fallback: use file mtime if content is not a valid timestamp.
		info, statErr := os.Stat(path)
		if statErr != nil {
			fmt.Fprintf(os.Stderr, "healthcheck file: cannot stat %s: %v\n", path, statErr)
			os.Exit(1)
		}
		ts = info.ModTime()
	}

	age := time.Since(ts)
	if age > time.Duration(maxAgeSec)*time.Second {
		fmt.Fprintf(os.Stderr, "healthcheck file: %s is %.0fs old (max %ds)\n", path, age.Seconds(), maxAgeSec)
		os.Exit(1)
	}
}
