package cli

import (
	"context"
	"errors"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"gitea.maximumdirect.net/eric/notarius/internal/core/artifacts"
	"gitea.maximumdirect.net/eric/notarius/internal/core/config"
	"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
	"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
)

func TestOversizedNPCRegistryFailsBeforeRuntimeAndCheckpointConstruction(t *testing.T) {
	components := productionTestComponents(t)
	npcPath := filepath.Join(t.TempDir(), "npcs.json")
	if err := os.WriteFile(npcPath, []byte(strings.Repeat("x", 1048577)), 0o600); err != nil {
		t.Fatal(err)
	}
	checkpointRoot := filepath.Join(t.TempDir(), "checkpoints")
	content := fmt.Sprintf(`version: 4
cache:
  chunk_plans:
    mode: bypass
  checkpoints:
    enabled: true
    directory: %q
pipelines:
  dnd-session:
    input: seriatim
    artifacts:
      spells:
        extract:
          module: dnd/spells
          references:
            npc_registry: %q
        normalize: dnd/spells
`, checkpointRoot, npcPath)
	configPath := filepath.Join(t.TempDir(), "config.yml")
	if err := os.WriteFile(configPath, []byte(content), 0o600); err != nil {
		t.Fatal(err)
	}

	llmConstructed := false
	chunkStoreConstructed := false
	options := Options{
		Catalog:    catalogFromRegistries(components.registries),
		Registries: components.registries,
		LLMClientFactory: func(context.Context, config.Config, string, LLMRuntimeOverrides) (contracts.StructuredLLMClient, []artifacts.LLMProfileManifest, error) {
			llmConstructed = true
			return nil, nil, errors.New("LLM client must not be constructed")
		},
		ChunkPlanStoreFactory: func(string) (pipeline.ChunkPlanStore, error) {
			chunkStoreConstructed = true
			return nil, errors.New("chunk-plan store must not be constructed")
		},
	}
	var stdout, stderr strings.Builder
	code := RunWithOptions([]string{
		"run", "dnd-session", "--config", configPath,
		"--input", repositoryPath("examples", "seriatim-minimal-transcript.json"),
		"--chunk_cache", "bypass", "--output-dir", t.TempDir(),
	}, &stdout, &stderr, options)
	for _, fragment := range []string{`pipeline "dnd-session"`, `reference slot "npc_registry"`, "1048577 bytes", "limit 1048576"} {
		if code == 0 || !strings.Contains(stderr.String(), fragment) {
			t.Fatalf("RunWithOptions() code = %d stderr = %q, want context fragment %q", code, stderr.String(), fragment)
		}
	}
	if llmConstructed || chunkStoreConstructed {
		t.Fatalf("runtime construction = LLM %t, chunk store %t; want materialization failure first", llmConstructed, chunkStoreConstructed)
	}
	if _, err := os.Stat(checkpointRoot); !errors.Is(err, fs.ErrNotExist) {
		t.Fatalf("checkpoint root stat error = %v, want no checkpoint allocation", err)
	}
}
