package pipeline

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

const generatedToolsMarker = "Generated by CLI Printing Press"

type MCPSurfaceState string

const (
	MCPSurfaceMissing    MCPSurfaceState = "missing"
	MCPSurfaceRuntime    MCPSurfaceState = "runtime_walking"
	MCPSurfaceStaticList MCPSurfaceState = "static_list"
	MCPSurfaceHandEdited MCPSurfaceState = "hand_edited"
	MCPSurfaceUnknown    MCPSurfaceState = "unknown_generated"
)

type MCPSurfaceResult struct {
	State      MCPSurfaceState `json:"state"`
	Pass       bool            `json:"pass"`
	Skipped    bool            `json:"skipped,omitempty"`
	HandEdited bool            `json:"hand_edited,omitempty"`
	Detail     string          `json:"detail"`
}

func InspectMCPSurface(dir string) (MCPSurfaceResult, error) {
	path := filepath.Join(dir, "internal", "mcp", "tools.go")
	data, err := os.ReadFile(path)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			return MCPSurfaceResult{
				State:   MCPSurfaceMissing,
				Skipped: true,
				Pass:    true,
				Detail:  "no internal/mcp/tools.go; CLI does not ship an MCP surface",
			}, nil
		}
		return MCPSurfaceResult{}, fmt.Errorf("reading %s: %w", path, err)
	}
	return ClassifyMCPSurface(string(data)), nil
}

func ClassifyMCPSurface(src string) MCPSurfaceResult {
	hasMarker := strings.Contains(src, generatedToolsMarker)
	hasWalker := strings.Contains(src, "cobratree.RegisterAll")
	hasStaticList := strings.Contains(src, "RegisterNovelFeatureTools") &&
		(strings.Contains(src, "shellOutToCLI(") || strings.Contains(src, "siblingCLIPath()"))

	switch {
	case hasMarker && hasWalker:
		return MCPSurfaceResult{State: MCPSurfaceRuntime, Pass: true, Detail: "MCP surface mirrors the Cobra tree at runtime"}
	case hasMarker && hasStaticList:
		return MCPSurfaceResult{State: MCPSurfaceStaticList, Pass: false, Detail: "static novel-feature MCP list detected; run `cli-printing-press mcp-sync <cli-dir>`"}
	case !hasMarker:
		return MCPSurfaceResult{State: MCPSurfaceHandEdited, Pass: true, HandEdited: true, Detail: "tools.go appears hand-edited; mcp-sync will not overwrite it without --force"}
	default:
		return MCPSurfaceResult{State: MCPSurfaceUnknown, Pass: false, Detail: "generated MCP tools.go does not use the runtime Cobra-tree template"}
	}
}

func IsRuntimeWalkingTemplate(toolsGoPath string) (bool, error) {
	data, err := os.ReadFile(toolsGoPath)
	if err != nil {
		return false, err
	}
	result := ClassifyMCPSurface(string(data))
	return result.State == MCPSurfaceRuntime, nil
}
