package infra

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

func TestGoBuildBinary(t *testing.T) {
	t.Run("compila proyecto valido sin error", func(t *testing.T) {
		// Crear un proyecto Go mínimo en un directorio temporal
		tmpDir := t.TempDir()
		goModContent := "module testapp\n\ngo 1.21\n"
		mainContent := `package main

import "fmt"

func main() {
	fmt.Println("hello")
}
`
		if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(goModContent), 0o644); err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(mainContent), 0o644); err != nil {
			t.Fatal(err)
		}

		outputPath := filepath.Join(tmpDir, "bin", "testapp")
		err := GoBuildBinary(tmpDir, outputPath, "", "")
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		// Verificar que el binario existe
		if _, statErr := os.Stat(outputPath); os.IsNotExist(statErr) {
			t.Errorf("binary not found at %s", outputPath)
		}
	})

	t.Run("outputPath vacio usa build/dirname por defecto", func(t *testing.T) {
		tmpDir := t.TempDir()
		goModContent := "module myproject\n\ngo 1.21\n"
		mainContent := "package main\n\nfunc main() {}\n"
		if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(goModContent), 0o644); err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(mainContent), 0o644); err != nil {
			t.Fatal(err)
		}

		err := GoBuildBinary(tmpDir, "", "", "")
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		expectedPath := filepath.Join(tmpDir, "build", filepath.Base(tmpDir))
		if _, statErr := os.Stat(expectedPath); os.IsNotExist(statErr) {
			t.Errorf("expected binary at %s, not found", expectedPath)
		}
	})

	t.Run("ldflags vacio usa -s -w por defecto", func(t *testing.T) {
		// Este test verifica que la función no falla con ldflags vacío
		// (los flags por defecto -s -w son válidos para go build)
		tmpDir := t.TempDir()
		if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte("module x\n\ngo 1.21\n"), 0o644); err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte("package main\n\nfunc main() {}\n"), 0o644); err != nil {
			t.Fatal(err)
		}

		outputPath := filepath.Join(tmpDir, "out")
		err := GoBuildBinary(tmpDir, outputPath, "", "")
		if err != nil {
			t.Errorf("ldflags vacío debería usar -s -w y compilar sin error: %v", err)
		}
	})

	t.Run("error si projectDir no existe", func(t *testing.T) {
		err := GoBuildBinary("/nonexistent/path/to/project", "/tmp/out", "", "")
		if err == nil {
			t.Error("expected error for nonexistent projectDir, got nil")
		}
	})
}
