package codereview

import (
	"bytes"
	"cmp"
	"context"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"slices"
	"strings"
	"testing"

	"golang.org/x/tools/txtar"
)

// updateTests is set to true when the -update flag is used.
// This will update the expected test results instead of failing tests.
var updateTests = flag.Bool("update", false, "update expected test results instead of failing tests")

// TestCodereviewDifferential runs all the end-to-end tests for the codereview and differential packages.
// Each test is defined in a .txtar file in the testdata directory.
func TestCodereviewDifferential(t *testing.T) {
	entries, err := os.ReadDir("testdata")
	if err != nil {
		t.Fatalf("failed to read testdata directory: %v", err)
	}
	for _, entry := range entries {
		if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".txtar") {
			continue
		}
		testPath := filepath.Join("testdata", entry.Name())
		testName := strings.TrimSuffix(entry.Name(), ".txtar")
		t.Run(testName, func(t *testing.T) {
			t.Parallel()
			runE2ETest(t, testPath, *updateTests)
		})
	}
}

// runE2ETest executes a single end-to-end test from a .txtar file.
func runE2ETest(t *testing.T, testPath string, update bool) {
	orig, err := os.ReadFile(testPath)
	if err != nil {
		t.Fatalf("failed to read test file %s: %v", testPath, err)
	}
	archive, err := txtar.ParseFile(testPath)
	if err != nil {
		t.Fatalf("failed to parse txtar file %s: %v", testPath, err)
	}

	tmpDir := t.TempDir()
	// resolve temp dir path so that we can canonicalize/normalize it later
	tmpDir = resolveRealPath(tmpDir)

	if err := initGoModule(tmpDir); err != nil {
		t.Fatalf("failed to initialize Go module: %v", err)
	}
	if err := initGitRepo(tmpDir); err != nil {
		t.Fatalf("failed to initialize git repository: %v", err)
	}
	if err := processTestFiles(t, archive, tmpDir, update); err != nil {
		t.Fatalf("error processing test files: %v", err)
	}

	// If we're updating, write back the modified archive to the file
	if update {
		updatedContent := txtar.Format(archive)
		// only write back changes, avoids git status churn
		if !bytes.Equal(orig, updatedContent) {
			if err := os.WriteFile(testPath, updatedContent, 0o644); err != nil {
				t.Errorf("Failed to update test file %s: %v", testPath, err)
			}
		}
	}
}

func gitCommitEnv() []string {
	return append(os.Environ(),
		"GIT_AUTHOR_NAME=Test Author",
		"GIT_AUTHOR_EMAIL=test@example.com",
		"GIT_COMMITTER_NAME=Test Committer",
		"GIT_COMMITTER_EMAIL=test@example.com",
		"GIT_AUTHOR_DATE=2025-01-01T00:00:00Z",
		"GIT_COMMITTER_DATE=2025-01-01T00:00:00Z",
	)
}

// initGitRepo initializes a new git repository in the specified directory.
func initGitRepo(dir string) error {
	cmd := exec.Command("git", "init")
	cmd.Dir = dir
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("error initializing git repository: %w", err)
	}
	// create a single commit out of everything there now
	cmd = exec.Command("git", "add", ".")
	cmd.Dir = dir
	err = cmd.Run()
	if err != nil {
		return fmt.Errorf("error staging files: %w", err)
	}
	cmd = exec.Command("git", "commit", "-m", "create repo")
	cmd.Dir = dir
	cmd.Env = gitCommitEnv()
	err = cmd.Run()
	if err != nil {
		return fmt.Errorf("error making initial commit: %w", err)
	}
	return nil
}

// processTestFiles processes the files in the txtar archive in sequence.
func processTestFiles(t *testing.T, archive *txtar.Archive, dir string, update bool) error {
	var initialCommit string
	filesForNextCommit := make(map[string]bool)

	for i, file := range archive.Files {
		switch file.Name {
		case ".commit":
			commit, err := makeGitCommit(dir, string(file.Data), filesForNextCommit)
			if err != nil {
				return fmt.Errorf("error making git commit: %w", err)
			}
			clear(filesForNextCommit)
			initialCommit = cmp.Or(initialCommit, commit)
			// fmt.Println("initial commit:", initialCommit)
			// cmd := exec.Command("git", "log")
			// cmd.Dir = dir
			// cmd.Stdout = os.Stdout
			// cmd.Run()

		case ".run_test":
			got, err := runDifferentialTest(dir, initialCommit)
			if err != nil {
				return fmt.Errorf("error running differential test: %w", err)
			}
			want := string(file.Data)

			commitCleaner := strings.NewReplacer(initialCommit, "INITIAL_COMMIT_HASH")
			got = commitCleaner.Replace(got)
			want = commitCleaner.Replace(want)

			if update {
				archive.Files[i].Data = []byte(got)
				break
			}
			if strings.TrimSpace(want) != strings.TrimSpace(got) {
				t.Errorf("Results don't match.\nExpected:\n%s\n\nActual:\n%s", want, got)
			}

		case ".run_autoformat":
			if initialCommit == "" {
				return fmt.Errorf("initial commit not set, cannot run autoformat")
			}

			got, err := runAutoformat(dir, initialCommit)
			if err != nil {
				return fmt.Errorf("error running autoformat: %w", err)
			}
			slices.Sort(got)

			if update {
				correct := strings.Join(got, "\n") + "\n"
				archive.Files[i].Data = []byte(correct)
				break
			}

			want := strings.Split(strings.TrimSpace(string(file.Data)), "\n")
			if !slices.Equal(want, got) {
				t.Errorf("Formatted files don't match.\nExpected:\n%s\n\nActual:\n%s", want, got)
			}

		default:
			filePath := filepath.Join(dir, file.Name)
			if err := os.MkdirAll(filepath.Dir(filePath), 0o700); err != nil {
				return fmt.Errorf("error creating directory for %s: %w", file.Name, err)
			}
			data := file.Data
			// Remove second trailing newline if present.
			// An annoyance of the txtar format, messes with gofmt.
			if bytes.HasSuffix(data, []byte("\n\n")) {
				data = bytes.TrimSuffix(data, []byte("\n"))
			}
			if err := os.WriteFile(filePath, file.Data, 0o600); err != nil {
				return fmt.Errorf("error writing file %s: %w", file.Name, err)
			}
			filesForNextCommit[file.Name] = true
		}
	}

	return nil
}

// makeGitCommit commits the specified files with the given message.
// Returns the commit hash.
func makeGitCommit(dir, message string, files map[string]bool) (string, error) {
	for file := range files {
		cmd := exec.Command("git", "add", file)
		cmd.Dir = dir
		if err := cmd.Run(); err != nil {
			return "", fmt.Errorf("error staging file %s: %w", file, err)
		}
	}
	message = cmp.Or(message, "Test commit")

	// Make the commit with fixed author, committer, and date for stable hashes
	cmd := exec.Command("git", "commit", "--allow-empty", "-m", message)
	cmd.Dir = dir
	cmd.Env = gitCommitEnv()
	if err := cmd.Run(); err != nil {
		return "", fmt.Errorf("error making commit: %w", err)
	}

	// Get the commit hash
	cmd = exec.Command("git", "rev-parse", "HEAD")
	cmd.Dir = dir
	out, err := cmd.Output()
	if err != nil {
		return "", fmt.Errorf("error getting commit hash: %w", err)
	}

	return strings.TrimSpace(string(out)), nil
}

// runDifferentialTest runs the code review tool on the repository and returns the result.
func runDifferentialTest(dir, initialCommit string) (string, error) {
	if initialCommit == "" {
		return "", fmt.Errorf("initial commit not set, cannot run differential test")
	}

	// Create a code reviewer for the repository
	ctx := context.Background()
	reviewer, err := NewCodeReviewer(ctx, dir, initialCommit, NoLLMReview)
	if err != nil {
		return "", fmt.Errorf("error creating code reviewer: %w", err)
	}

	// Run the code review
	result, err := reviewer.Run(ctx, nil)
	if err != nil {
		return "", fmt.Errorf("error running code review: %w", err)
	}

	// Normalize paths in the result
	resultStr := ""
	if len(result) > 0 {
		resultStr = result[0].Text
	}
	normalized := normalizePaths(resultStr, dir)
	return normalized, nil
}

// normalizePaths replaces the temp directory paths with a standard placeholder
func normalizePaths(result string, tempDir string) string {
	return strings.ReplaceAll(result, tempDir, "/PATH/TO/REPO")
}

// initGoModule initializes a Go module in the specified directory.
func initGoModule(dir string) error {
	cmd := exec.Command("go", "mod", "init", "sketch.dev")
	cmd.Dir = dir
	return cmd.Run()
}

// runAutoformat runs the autoformat function on the repository and returns the list of formatted files.
func runAutoformat(dir, initialCommit string) ([]string, error) {
	if initialCommit == "" {
		return nil, fmt.Errorf("initial commit not set, cannot run autoformat")
	}
	ctx := context.Background()
	reviewer, err := NewCodeReviewer(ctx, dir, initialCommit, NoLLMReview)
	if err != nil {
		return nil, fmt.Errorf("error creating code reviewer: %w", err)
	}
	formattedFiles := reviewer.autoformat(ctx)
	normalizedFiles := make([]string, len(formattedFiles))
	for i, file := range formattedFiles {
		normalizedFiles[i] = normalizePaths(file, dir)
	}
	slices.Sort(normalizedFiles)
	return normalizedFiles, nil
}

// resolveRealPath follows symlinks and returns the real path
// This handles platform-specific behaviors like macOS's /private prefix
func resolveRealPath(path string) string {
	// Follow symlinks to get the real path
	realPath, err := filepath.EvalSymlinks(path)
	if err != nil {
		// If we can't resolve symlinks, just return the original path
		return path
	}
	return realPath
}
