package action

import (
	"context"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestAnalyzeCodeActivity(t *testing.T) {
	// Create temp directory with some Go code
	tmpDir, err := os.MkdirTemp("", "analyze-test")
	require.NoError(t, err)
	defer os.RemoveAll(tmpDir)

	// Create go.mod
	goMod := `module test
go 1.21
`
	require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(goMod), 0644))

	// Create a simple Go file
	goCode := `package main

func main() {
	println("hello")
}
`
	require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(goCode), 0644))

	// Run activity
	output, err := AnalyzeCodeActivity(context.Background(), AnalyzeCodeInput{
		Path:  tmpDir,
		Depth: 3,
	})
	require.NoError(t, err)

	// Verify output
	require.Greater(t, output.Quality, 0.0)
	require.NotNil(t, output.Metrics)
	require.NotEmpty(t, output.Summary)
	
	totalFiles, ok := output.Metrics["totalFiles"].(int)
	require.True(t, ok)
	require.Equal(t, 1, totalFiles) // Just main.go (go.mod not counted)
}

func TestAnalyzeCodeActivity_PathNotExist(t *testing.T) {
	_, err := AnalyzeCodeActivity(context.Background(), AnalyzeCodeInput{
		Path: "/nonexistent/path",
	})
	require.Error(t, err)
	require.Contains(t, err.Error(), "does not exist")
}

func TestSecurityScanActivity(t *testing.T) {
	// Create temp directory
	tmpDir, err := os.MkdirTemp("", "security-test")
	require.NoError(t, err)
	defer os.RemoveAll(tmpDir)

	// Create a file with potential secret (matches pattern "password=")
	code := `package main

var config = map[string]string{
	"password=": "supersecret123",
	"api_key=": "sk-12345",
}
`
	require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(code), 0644))

	// Run activity
	output, err := SecurityScanActivity(context.Background(), SecurityScanInput{
		Path:     tmpDir,
		Severity: "medium",
	})
	require.NoError(t, err)

	// Should find the hardcoded password
	require.Greater(t, len(output.Vulnerabilities), 0)
	require.Less(t, output.SecurityScore, 100.0)
}

func TestSecurityScanActivity_Clean(t *testing.T) {
	// Create temp directory with clean code
	tmpDir, err := os.MkdirTemp("", "security-clean-test")
	require.NoError(t, err)
	defer os.RemoveAll(tmpDir)

	// Create clean code
	code := `package main

func main() {
	println("hello")
}
`
	require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(code), 0644))

	// Run activity
	output, err := SecurityScanActivity(context.Background(), SecurityScanInput{
		Path: tmpDir,
	})
	require.NoError(t, err)

	// Should be clean
	require.Equal(t, 0, len(output.Vulnerabilities))
	require.Equal(t, 100.0, output.SecurityScore)
	require.Equal(t, "low", output.RiskLevel)
}

func TestGenerateReportActivity(t *testing.T) {
	output, err := GenerateReportActivity(context.Background(), GenerateReportInput{
		AnalysisResult: map[string]interface{}{"quality": 0.85},
		SecurityResult: map[string]interface{}{"score": 95.0},
		Format:         "markdown",
	})
	require.NoError(t, err)

	require.Contains(t, output.Report, "# Analysis Report")
	require.NotEmpty(t, output.ReportPath)
	
	// Verify file was created
	_, err = os.Stat(output.ReportPath)
	require.NoError(t, err)
	
	// Cleanup
	os.Remove(output.ReportPath)
}

func TestGenerateReportActivity_JSON(t *testing.T) {
	output, err := GenerateReportActivity(context.Background(), GenerateReportInput{
		AnalysisResult: map[string]interface{}{"quality": 0.85},
		SecurityResult: map[string]interface{}{"score": 95.0},
		Format:         "json",
	})
	require.NoError(t, err)

	require.Contains(t, output.Report, `"timestamp"`)
	
	// Cleanup
	os.Remove(output.ReportPath)
}
