// Package flog is a structured logger formatted for GCP Cloud Logging.
//
// The API mirrors log/slog: a message string followed by alternating key/value
// pairs. Each kv pair becomes a JSON field in the emitted record, which Cloud
// Logging promotes to a queryable jsonPayload field.
//
//	flog.Info("particle processed", "particleID", id, "elapsed", dt)
package flog

import (
	"os"

	"github.com/sirupsen/logrus"
)

// Prepares global logger for GCP Cloud Logging's quirks
var log = func() *logrus.Logger {
	logger := logrus.New()
	logger.SetFormatter(&logrus.JSONFormatter{
		FieldMap: logrus.FieldMap{
			logrus.FieldKeyLevel: "severity",
			logrus.FieldKeyMsg:   "message",
			logrus.FieldKeyTime:  "timestamp",
		},
	})
	logger.SetOutput(os.Stderr)
	logger.SetLevel(logrus.DebugLevel)
	return logger
}()

// fields converts alternating key/value args into a logrus.Fields map. A
// trailing odd arg or non-string key is stored under "!BADKEY" to match
// slog's behavior.
func fields(args []any) logrus.Fields {
	if len(args) == 0 {
		return nil
	}
	f := make(logrus.Fields, len(args)/2+1)
	for i := 0; i < len(args); i += 2 {
		if i+1 >= len(args) {
			f["!BADKEY"] = args[i]
			break
		}
		key, ok := args[i].(string)
		if !ok {
			f["!BADKEY"] = args[i]
			continue
		}
		f[key] = args[i+1]
	}
	return f
}

func Debug(msg string, args ...any) { log.WithFields(fields(args)).Debug(msg) }
func Info(msg string, args ...any)  { log.WithFields(fields(args)).Info(msg) }
func Warn(msg string, args ...any)  { log.WithFields(fields(args)).Warn(msg) }
func Error(msg string, args ...any) { log.WithFields(fields(args)).Error(msg) }
func Fatal(msg string, args ...any) { log.WithFields(fields(args)).Fatal(msg) }
