package main

import (
	"encoding/json"
	"flag"
	"log"
	"net/http"
	"os"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/wangjia/pangolin/server/internal/redisutil"
	"github.com/wangjia/pangolin/server/internal/scheduler/probe"

	"github.com/wangjia/pangolin/server/api/gen"
	"github.com/wangjia/pangolin/server/internal/httpapi"
)

func main() {
	addr := flag.String("addr", "", "listen address (default :8080, overridden by ADDR env)")
	flag.Parse()

	if *addr == "" {
		if v := os.Getenv("ADDR"); v != "" {
			*addr = v
		} else {
			*addr = ":8080"
		}
	}

	r := chi.NewRouter()
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)

	// Health check — outside the versioned API.
	r.Get("/healthz", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		_ = json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
	})

	// --- Probe ingest route (optional) ---
	// Requires:
	//   PROBE_SECRETS  – JSON object mapping probeId → HMAC secret, e.g.
	//                    '{"probe-sg-01":"s3cr3t1","probe-jp-01":"s3cr3t2"}'
	//   REDIS_ADDR     – Redis address, default 127.0.0.1:6379
	//   REDIS_PASSWORD – Redis password (optional)
	//
	// If PROBE_SECRETS is empty the route is not registered and the server
	// starts normally without the probe ingest endpoint.
	probeSecretsJSON := os.Getenv("PROBE_SECRETS")
	if probeSecretsJSON != "" {
		redisAddr := getenvDefault("REDIS_ADDR", "127.0.0.1:6379")
		rdb, err := redisutil.New(redisAddr, os.Getenv("REDIS_PASSWORD"), 0)
		if err != nil {
			log.Printf("probe: redis connect failed (%v) – probe route disabled", err)
		} else {
			var secretMap map[string]string
			if err := json.Unmarshal([]byte(probeSecretsJSON), &secretMap); err != nil {
				log.Fatalf("probe: invalid PROBE_SECRETS JSON: %v", err)
			}
			reg := probe.NewMapRegistry(secretMap)
			st := probe.NewStore(rdb)
			h := probe.NewIngestHandler(reg, st)
			r.Post("/probe/report", h.ServeHTTP)
			log.Printf("probe ingest route registered (%d probe(s))", len(secretMap))
		}
	}
	// Mount all /v1/... routes.  HandlerFromMuxWithBaseURL registers every route
	// from the OpenAPI spec onto the provided chi router with the given prefix,
	// so the router itself is the http.Handler we serve.
	gen.HandlerFromMuxWithBaseURL(&httpapi.UnimplementedServer{}, r, "/v1")

	log.Printf("pangolin server listening on %s", *addr)
	if err := http.ListenAndServe(*addr, r); err != nil {
		log.Fatalf("server error: %v", err)
	}
}

func getenvDefault(key, def string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return def
}
