package tests

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

	"github.com/jfraeys/fetch_ml/internal/fileutil"
	tests "github.com/jfraeys/fetch_ml/tests/fixtures"
)

// TestExampleProjects validates that all example projects have valid structure
func TestExampleProjects(t *testing.T) {
	// Use fixtures for examples directory operations
	examplesDir := tests.NewExamplesDir("../fixtures/examples")

	projects := []string{
		"standard_ml_project",
		"sklearn_project",
		"xgboost_project",
		"pytorch_project",
		"tensorflow_project",
		"statsmodels_project",
	}

	for _, project := range projects {
		t.Run(project, func(t *testing.T) {
			projectDir := examplesDir.GetPath(project)

			// Check project directory exists
			t.Logf("Checking project directory: %s", projectDir)
			if _, err := os.Stat(projectDir); os.IsNotExist(err) {
				t.Fatalf("Example project %s does not exist", project)
			}

			// Check required files
			requiredFiles := []string{"train.py", "requirements.txt", "README.md"}
			for _, file := range requiredFiles {
				filePath := filepath.Join(projectDir, file)
				if _, err := os.Stat(filePath); os.IsNotExist(err) {
					t.Errorf("Missing required file %s in project %s", file, project)
				}
			}

			// Validate train.py is executable
			trainPath := filepath.Join(projectDir, "train.py")
			info, err := os.Stat(trainPath)
			if err != nil {
				t.Fatalf("Cannot stat train.py: %v", err)
			}
			if info.Mode().Perm()&0111 == 0 {
				t.Errorf("train.py should be executable in project %s", project)
			}
		})
	}
}

// Helper function to execute commands and return output
func executeCommand(name string, args ...string) (string, error) {
	cmd := exec.CommandContext(context.Background(), name, args...)
	output, err := cmd.CombinedOutput()
	return string(output), err
}

// TestExampleExecution tests that examples can be executed (dry run)
func TestExampleExecution(t *testing.T) {
	examplesDir := "../fixtures/examples"

	projects := []string{
		"standard_ml_project",
		"sklearn_project",
	}

	for _, project := range projects {
		t.Run(project, func(t *testing.T) {
			projectDir := filepath.Join(examplesDir, project)
			trainScript := filepath.Join(projectDir, "train.py")

			// Test script syntax by checking if it can be parsed
			output, err := executeCommand("python3", "-m", "py_compile", trainScript)
			if err != nil {
				t.Errorf("Failed to compile %s: %v", project, err)
			}

			// If compilation succeeds, the syntax is valid
			if len(output) > 0 {
				t.Logf("Compilation output for %s: %s", project, output)
			}
		})
	}
}

// TestPodmanWorkspaceSync tests example projects structure using temporary directory
func TestPodmanWorkspaceSync(t *testing.T) {
	// Use fixtures for examples directory operations
	examplesDir := tests.NewExamplesDir("../fixtures/examples")

	// Use temporary directory for test workspace
	tempDir := t.TempDir()
	podmanDir := filepath.Join(tempDir, "podman/workspace")

	// Copy examples to temp workspace
	if err := os.MkdirAll(podmanDir, 0750); err != nil {
		t.Fatalf("Failed to create test workspace: %v", err)
	}

	// Get list of example projects using fixtures
	entries, err := os.ReadDir("../fixtures/examples")
	if err != nil {
		t.Fatalf("Failed to read examples directory: %v", err)
	}

	for _, entry := range entries {
		if !entry.IsDir() {
			continue
		}

		projectName := entry.Name()

		// Copy project to temp workspace using fixtures
		dstDir := filepath.Join(podmanDir, projectName)
		err := examplesDir.CopyProject(projectName, dstDir)
		if err != nil {
			t.Fatalf("Failed to copy %s to test workspace: %v", projectName, err)
		}

		t.Run(projectName, func(t *testing.T) {
			// Compare key files
			files := []string{"train.py", "requirements.txt"}
			for _, file := range files {
				exampleFile := filepath.Join(examplesDir.GetPath(projectName), file)
				podmanFile := filepath.Join(podmanDir, projectName, file)

				exampleContent, err1 := fileutil.SecureFileRead(exampleFile)
				podmanContent, err2 := fileutil.SecureFileRead(podmanFile)

				if err1 != nil {
					t.Errorf("Cannot read %s from examples/: %v", file, err1)
					continue
				}
				if err2 != nil {
					t.Errorf("Cannot read %s from test workspace: %v", file, err2)
					continue
				}

				if string(exampleContent) != string(podmanContent) {
					t.Errorf("File %s differs between examples/ and test workspace for project %s", file, projectName)
				}
			}
		})
	}
}
