package toolingplan

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"

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

func repoManagedTools(repoRoot string) (map[string]struct{}, []SkipNote) {
	tools := make(map[string]struct{})
	skips := make([]SkipNote, 0)
	if err := collectToolVersions(filepath.Join(repoRoot, ".tool-versions"), tools); err != nil {
		skips = append(skips, SkipNote{
			Target: "repo mise declarations",
			Reason: fmt.Sprintf("could not read .tool-versions: %v", err),
		})
	}
	if err := collectMiseToml(filepath.Join(repoRoot, ".mise.toml"), tools); err != nil {
		skips = append(skips, SkipNote{
			Target: "repo mise declarations",
			Reason: fmt.Sprintf("could not parse .mise.toml: %v", err),
		})
	}
	return tools, skips
}

func collectToolVersions(path string, tools map[string]struct{}) error {
	file, err := os.Open(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		fields := strings.Fields(line)
		if len(fields) == 0 {
			continue
		}
		tools[fields[0]] = struct{}{}
	}
	return scanner.Err()
}

func collectMiseToml(path string, tools map[string]struct{}) error {
	data, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	tree, err := toml.LoadBytes(data)
	if err != nil {
		return err
	}
	value := tree.Get("tools")
	if value == nil {
		return nil
	}
	switch typed := value.(type) {
	case *toml.Tree:
		for _, key := range typed.Keys() {
			tools[key] = struct{}{}
		}
	case map[string]interface{}:
		keys := make([]string, 0, len(typed))
		for key := range typed {
			keys = append(keys, key)
		}
		sort.Strings(keys)
		for _, key := range keys {
			tools[key] = struct{}{}
		}
	}
	return nil
}
