package module

import (
	"context"
	"encoding/json"
	"testing"

	"github.com/gin-gonic/gin"
	"kra/pkg/database/migration"
	"kra/pkg/task"
)

func TestCatalogCollectsContributions(t *testing.T) {
	run := func(context.Context, json.RawMessage) error { return nil }
	catalog := Catalog{Definitions: []Definition{
		{
			Name:       "system",
			Migrations: []migration.Step{{ID: "system_schema"}},
			Surface:    Surface{Menus: []Menu{{Name: "users"}}, APIs: []API{{Path: "/users"}}},
			TimedTasks: []TimedTask{{Name: "system.cleanup"}},
			Tasks:      []task.Method{{Name: "system.cleanup", Run: run}},
		},
		{
			Name:       "orders",
			Migrations: []migration.Step{{ID: "orders_schema"}},
			Surface:    Surface{Menus: []Menu{{Name: "orders"}}, APIs: []API{{Path: "/orders"}}},
			TimedTasks: []TimedTask{{Name: "orders.expire"}},
			Tasks:      []task.Method{{Name: "orders.expire", Run: run}},
		},
	}}

	if got := catalog.MigrationSteps(); len(got) != 2 || got[0].ID != "system_schema" || got[1].ID != "orders_schema" {
		t.Fatalf("unexpected migrations: %#v", got)
	}
	if got := catalog.Surface(); len(got.Menus) != 2 || len(got.APIs) != 2 || got.Menus[1].Name != "orders" {
		t.Fatalf("unexpected surface: %#v", got)
	}
	if got := catalog.DefaultTimedTasks(); len(got) != 2 || got[1].Name != "orders.expire" {
		t.Fatalf("unexpected default tasks: %#v", got)
	}
	if got := catalog.TaskMethods(); len(got) != 2 || got[1].Name != "orders.expire" {
		t.Fatalf("unexpected task methods: %#v", got)
	}
}

type routeRegistrarStub struct{ called bool }

func (stub *routeRegistrarStub) RegisterRoutes(*gin.RouterGroup, *gin.RouterGroup, *gin.Engine) {
	stub.called = true
}

func TestRuntimeSkipsNilRouteRegistrars(t *testing.T) {
	stub := &routeRegistrarStub{}
	runtime := NewRuntime(nil, stub)
	runtime.RegisterRoutes(nil, nil, nil)
	if !stub.called {
		t.Fatal("non-nil route registrar was not called")
	}
}
