package dsl

import (
	"sort"
	"strings"
)

const (
	// AgentTeamCheckoutUse is the AgentTeam-native checkout step supported by MeshX.
	AgentTeamCheckoutUse = "agentteam/checkout"

	// AgentTeamCheckoutWithPath is the checkout destination path option.
	AgentTeamCheckoutWithPath = "path"
	// AgentTeamCheckoutWithClean controls whether checkout removes the destination first.
	AgentTeamCheckoutWithClean = "clean"
)

// AgentTeamCheckoutOptions are the normalized options for a agentteam/checkout step.
type AgentTeamCheckoutOptions struct {
	Path  string
	Clean bool
}

// AgentTeamCheckoutOptionError describes one invalid agentteam/checkout option.
type AgentTeamCheckoutOptionError struct {
	Code    string
	Key     string
	Message string
}

func (e AgentTeamCheckoutOptionError) Error() string {
	return e.Message
}

// ParseAgentTeamCheckoutOptions validates and normalizes agentteam/checkout with values.
func ParseAgentTeamCheckoutOptions(values map[string]any) (AgentTeamCheckoutOptions, []AgentTeamCheckoutOptionError) {
	options := AgentTeamCheckoutOptions{Path: ".", Clean: true}
	keys := make([]string, 0, len(values))
	for key := range values {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	var errs []AgentTeamCheckoutOptionError
	for _, key := range keys {
		value := values[key]
		switch key {
		case AgentTeamCheckoutWithPath:
			path, ok := value.(string)
			if !ok || strings.TrimSpace(path) == "" || AgentTeamCheckoutPathHasGitSegment(path) {
				errs = append(errs, AgentTeamCheckoutOptionError{
					Code:    "agentteam_checkout_path_invalid",
					Key:     key,
					Message: "agentteam/checkout with.path must be a non-empty path outside .git control directories",
				})
				continue
			}
			options.Path = strings.TrimSpace(path)
		case AgentTeamCheckoutWithClean:
			clean, ok := parseAgentTeamCheckoutClean(value)
			if !ok {
				errs = append(errs, AgentTeamCheckoutOptionError{
					Code:    "agentteam_checkout_clean_invalid",
					Key:     key,
					Message: "agentteam/checkout with.clean must be a boolean",
				})
				continue
			}
			options.Clean = clean
		default:
			errs = append(errs, AgentTeamCheckoutOptionError{
				Code:    "agentteam_checkout_with_unsupported",
				Key:     key,
				Message: "agentteam/checkout only supports with.path and with.clean",
			})
		}
	}
	return options, errs
}

// AgentTeamCheckoutPathHasGitSegment reports whether pathValue names a .git control
// directory segment before path cleaning.
func AgentTeamCheckoutPathHasGitSegment(pathValue string) bool {
	for _, segment := range strings.FieldsFunc(strings.TrimSpace(pathValue), func(r rune) bool {
		return r == '/' || r == '\\'
	}) {
		if strings.EqualFold(segment, ".git") {
			return true
		}
	}
	return false
}

func parseAgentTeamCheckoutClean(value any) (bool, bool) {
	switch typed := value.(type) {
	case bool:
		return typed, true
	case string:
		switch strings.ToLower(strings.TrimSpace(typed)) {
		case "true":
			return true, true
		case "false":
			return false, true
		default:
			return false, false
		}
	default:
		return false, false
	}
}
