package exploit

import (
	"sort"

	"github.com/Armur-Ai/Pentest-Swarm-AI/internal/pipeline"
	"github.com/google/uuid"
)

// relationship defines how one finding type can lead to another.
type relationship struct {
	from string
	to   []string
}

// predefined attack chain relationships
var chainRules = []relationship{
	{from: "sqli", to: []string{"data_extraction", "auth_bypass", "file_read"}},
	{from: "path_traversal", to: []string{"file_read", "source_code_disclosure", "credential_access"}},
	{from: "open_redirect", to: []string{"phishing_amplification", "oauth_bypass"}},
	{from: "exposed_git", to: []string{"source_code_disclosure", "credential_extraction", "secret_discovery"}},
	{from: "weak_credentials", to: []string{"authentication_bypass", "privilege_escalation"}},
	{from: "outdated_software", to: []string{"known_exploit"}},
	{from: "misconfigured_cors", to: []string{"cross_origin_data_theft"}},
	{from: "xxe", to: []string{"ssrf", "file_read", "internal_network_scan"}},
	{from: "ssrf", to: []string{"internal_network_scan", "cloud_metadata_access", "port_scan"}},
	{from: "xss", to: []string{"session_hijack", "credential_theft", "phishing"}},
	{from: "rce", to: []string{"full_system_access", "lateral_movement", "data_exfiltration"}},
	{from: "lfi", to: []string{"file_read", "rce_via_log_poisoning", "credential_access"}},
	{from: "idor", to: []string{"data_extraction", "privilege_escalation"}},
}

// PathBuilder constructs attack chains from classified findings using predefined rules.
type PathBuilder struct{}

// NewPathBuilder creates a new path builder.
func NewPathBuilder() *PathBuilder {
	return &PathBuilder{}
}

// BuildChains constructs all valid attack chains from the given findings.
func (p *PathBuilder) BuildChains(findings []pipeline.ClassifiedFinding) []pipeline.AttackPath {
	var paths []pipeline.AttackPath

	for _, finding := range findings {
		category := finding.AttackCategory
		if category == "" {
			continue
		}

		for _, rule := range chainRules {
			if rule.from != category {
				continue
			}

			// Build a path for each possible chain
			for _, target := range rule.to {
				path := pipeline.AttackPath{
					ID:          uuid.New(),
					Name:        category + " → " + target,
					Description: "Chain from " + finding.Title + " to " + target,
					Steps: []pipeline.AttackStep{
						{
							ID:   uuid.New(),
							Name: "Exploit " + finding.Title,
						},
						{
							ID:   uuid.New(),
							Name: "Achieve " + target,
						},
					},
					TargetFindingIDs:            []uuid.UUID{finding.ID},
					EstimatedSuccessProbability: estimateSuccess(finding, target),
					ExpectedImpact:              impactLevel(target),
				}
				paths = append(paths, path)
			}
		}
	}

	// Sort by estimated success probability descending
	sort.Slice(paths, func(i, j int) bool {
		return paths[i].EstimatedSuccessProbability > paths[j].EstimatedSuccessProbability
	})

	return paths
}

func estimateSuccess(finding pipeline.ClassifiedFinding, target string) float64 {
	// Base probability from finding confidence
	base := 0.5
	switch finding.Confidence {
	case pipeline.ConfidenceHigh:
		base = 0.8
	case pipeline.ConfidenceMedium:
		base = 0.6
	case pipeline.ConfidenceLow:
		base = 0.3
	}

	// Adjust based on chain complexity
	complexTargets := map[string]float64{
		"full_system_access":    0.6,
		"lateral_movement":      0.5,
		"privilege_escalation":  0.7,
		"cloud_metadata_access": 0.8,
		"data_extraction":       0.9,
		"session_hijack":        0.7,
	}

	if modifier, ok := complexTargets[target]; ok {
		base *= modifier
	}

	return base
}

func impactLevel(target string) string {
	highImpact := map[string]bool{
		"full_system_access": true, "rce_via_log_poisoning": true,
		"lateral_movement": true, "data_exfiltration": true,
		"credential_access": true, "privilege_escalation": true,
	}
	if highImpact[target] {
		return "high"
	}
	return "medium"
}
