package report

import (
	"strings"
	"testing"

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

// TestToMarkdown_RendersStepsToReproduce pins D.10.3: the default markdown
// report must surface the copy-pasteable repro block, not just the H1/
// Bugcrowd submission templates.
func TestToMarkdown_RendersStepsToReproduce(t *testing.T) {
	report := &pipeline.PentestReport{
		Target: "acme.corp",
		Findings: []pipeline.ReportFinding{{
			Title:    "SQL injection in /search",
			Severity: pipeline.SeverityCritical,
			Reproduce: &pipeline.Reproduction{
				Command:           "sqlmap --batch -u 'https://acme.corp/search?q=1'",
				HTTPRequest:       "GET /search?q=1'+OR+1=1-- HTTP/1.1\r\nHost: acme.corp",
				ExpectedIndicator: "You have an error in your SQL syntax",
			},
		}},
	}

	md, err := NewRenderer().ToMarkdown(report)
	if err != nil {
		t.Fatalf("ToMarkdown: %v", err)
	}
	out := string(md)
	for _, want := range []string{
		"**Steps to Reproduce:**",
		"sqlmap --batch -u 'https://acme.corp/search?q=1'",
		"GET /search?q=1'+OR+1=1-- HTTP/1.1",
		"Expected indicator: `You have an error in your SQL syntax`",
	} {
		if !strings.Contains(out, want) {
			t.Errorf("markdown missing %q\n---\n%s", want, out)
		}
	}
}

// TestToMarkdown_RendersClassification pins D.10.1: OWASP + CWE labels show
// up in the report when present, and are omitted when not.
func TestToMarkdown_RendersClassification(t *testing.T) {
	withTags := &pipeline.PentestReport{Findings: []pipeline.ReportFinding{{
		Title: "SQL injection in /search", Severity: pipeline.SeverityCritical,
		OWASP: "A03:2021-Injection", CWE: "CWE-89", ATTACK: "T1190 Exploit Public-Facing Application",
	}}}
	md, err := NewRenderer().ToMarkdown(withTags)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(string(md), "**Classification:** OWASP A03:2021-Injection · CWE-89 · ATT&CK T1190 Exploit Public-Facing Application") {
		t.Errorf("classification line missing:\n%s", md)
	}

	noTags := &pipeline.PentestReport{Findings: []pipeline.ReportFinding{{
		Title: "Some finding", Severity: pipeline.SeverityLow,
	}}}
	md2, _ := NewRenderer().ToMarkdown(noTags)
	if strings.Contains(string(md2), "Classification:") {
		t.Errorf("unexpected classification line for untagged finding:\n%s", md2)
	}
}

// TestToMarkdown_NoReproBlockWhenEmpty ensures we don't print an empty
// "Steps to Reproduce" header for findings with no repro content (e.g. a
// Reproduction carrying only Tools, or nil).
func TestToMarkdown_NoReproBlockWhenEmpty(t *testing.T) {
	for _, f := range []pipeline.ReportFinding{
		{Title: "no repro", Severity: pipeline.SeverityLow},
		{Title: "tools only", Severity: pipeline.SeverityLow, Reproduce: &pipeline.Reproduction{Tools: []string{"nuclei"}}},
	} {
		md, err := NewRenderer().ToMarkdown(&pipeline.PentestReport{Findings: []pipeline.ReportFinding{f}})
		if err != nil {
			t.Fatal(err)
		}
		if strings.Contains(string(md), "Steps to Reproduce") {
			t.Errorf("%q: unexpected repro block for empty reproduction", f.Title)
		}
	}
}
