package toolingplan

import (
	"context"
	"fmt"
	"strings"

	toml "github.com/pelletier/go-toml"
)

type rustDetector struct{}

func (rustDetector) detect(_ context.Context, repoRoot string, managedTools map[string]struct{}) detectionResult {
	if alreadyManaged("rust", managedTools) {
		return detectionResult{Skips: []SkipNote{{Target: "rust", Reason: "already managed by repo mise declarations"}}}
	}
	if version, ok, reason := parseRustToolchainToml(repoRoot); ok {
		return detectionResult{Steps: []InstallStep{{Tool: "rust", Version: version, Source: "rust-toolchain.toml", Reason: "exact toolchain channel"}}}
	} else if reason != "" {
		return detectionResult{Skips: []SkipNote{{Target: "rust", Reason: reason}}}
	}
	value, ok, err := readRepoFile(repoRoot, "rust-toolchain")
	if err != nil {
		return detectionResult{Skips: []SkipNote{{Target: "rust", Reason: fmt.Sprintf("could not read rust-toolchain: %v", err)}}}
	}
	if !ok {
		return detectionResult{Skips: []SkipNote{{Target: "rust", Reason: "no rust-toolchain or rust-toolchain.toml"}}}
	}
	version := firstMeaningfulLine(value)
	if normalized, ok := normalizeExactVersion(version); ok {
		return detectionResult{Steps: []InstallStep{{Tool: "rust", Version: normalized, Source: "rust-toolchain", Reason: "exact toolchain channel"}}}
	}
	return detectionResult{Skips: []SkipNote{{Target: "rust", Reason: "rust-toolchain does not pin an exact version"}}}
}

func parseRustToolchainToml(repoRoot string) (version string, ok bool, reason string) {
	data, found, err := readRepoFile(repoRoot, "rust-toolchain.toml")
	if err != nil {
		return "", false, fmt.Sprintf("could not read rust-toolchain.toml: %v", err)
	}
	if !found {
		return "", false, ""
	}
	tree, err := toml.Load(data)
	if err != nil {
		return "", false, fmt.Sprintf("could not parse rust-toolchain.toml: %v", err)
	}
	channelValue := tree.GetDefault("toolchain.channel", "")
	channel, _ := channelValue.(string)
	channel = strings.TrimSpace(channel)
	if channel == "" {
		return "", false, "rust-toolchain.toml has no toolchain.channel"
	}
	version, ok = normalizeExactVersion(channel)
	if !ok {
		return "", false, "rust-toolchain.toml channel is not an exact version"
	}
	return version, true, ""
}

func firstMeaningfulLine(value string) string {
	for _, line := range strings.Split(value, "\n") {
		trimmed := strings.TrimSpace(line)
		if trimmed == "" || strings.HasPrefix(trimmed, "#") {
			continue
		}
		return trimmed
	}
	return ""
}
