// Package openapitest holds a cross-module guard: it registers every module
// into one Huma API and generates the spec. Huma names OpenAPI schemas by Go
// type name alone (not package-qualified), so two modules declaring an
// identically named response type (e.g. two "ListOutput"s) collide only when
// registered together - a failure invisible to per-package `go build`/`go test`.
package openapitest

import (
	"net/http"
	"path/filepath"
	"testing"

	"nadir/internal/auditlog"
	"nadir/internal/auth"
	"nadir/internal/meta"
	"nadir/internal/module"
	"nadir/internal/modules/groups"
	"nadir/internal/modules/networking"
	"nadir/internal/modules/packages"
	"nadir/internal/modules/services"
	"nadir/internal/modules/storage"
	"nadir/internal/modules/system"
	"nadir/internal/modules/users"
	"nadir/internal/rbac"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humago"
)

type auditModule struct{}

func (auditModule) ID() string                     { return "audit" }
func (auditModule) Permissions() []rbac.Permission { return []rbac.Permission{rbac.Read} }
func (auditModule) Register(huma.API)              {}

func TestOpenAPISchemaNoCollisions(t *testing.T) {
	auditStore, err := auditlog.New(filepath.Join(t.TempDir(), "audit.db"))
	if err != nil {
		t.Fatal(err)
	}
	sessions, err := auth.NewSessionStore(filepath.Join(t.TempDir(), "sessions.db"))
	if err != nil {
		t.Fatal(err)
	}
	roles := rbac.New()

	// Mirror cmd/server.go's registration so this catches real collisions.
	mods := []module.Module{
		system.New(),
		services.New(nil),
		users.New(nil),
		groups.New(),
		packages.New(),
		networking.New(),
		storage.New(),
		auditModule{},
	}

	mux := http.NewServeMux()
	api := humago.New(mux, huma.DefaultConfig("test", "1.0.0"))
	for _, m := range mods {
		m.Register(api) // huma panics here on a duplicate schema name
	}
	meta.Register(api, mods)
	meta.RegisterHealth(api, sessions)
	meta.RegisterWhoami(api, sessions, nil, roles, mods)
	meta.RegisterAudit(api, auditStore)
	auth.RegisterLogin(api, sessions, auditStore, true)
	auth.RegisterLogout(api, sessions, true)

	// Force full schema resolution.
	if _, err := api.OpenAPI().YAML(); err != nil {
		t.Fatalf("OpenAPI generation failed: %v", err)
	}
}
