package claudetool

import (
	"context"
	"encoding/json"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"testing"
	"time"
)

func TestBashRun(t *testing.T) {
	// Test basic functionality
	t.Run("Basic Command", func(t *testing.T) {
		input := json.RawMessage(`{"command":"echo 'Hello, world!'"}`)

		result, err := BashRun(context.Background(), input)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		expected := "Hello, world!\n"
		resultStr := ContentToString(result)
		if resultStr != expected {
			t.Errorf("Expected %q, got %q", expected, resultStr)
		}
	})

	// Test with arguments
	t.Run("Command With Arguments", func(t *testing.T) {
		input := json.RawMessage(`{"command":"echo -n foo && echo -n bar"}`)

		result, err := BashRun(context.Background(), input)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		expected := "foobar"
		resultStr := ContentToString(result)
		if resultStr != expected {
			t.Errorf("Expected %q, got %q", expected, resultStr)
		}
	})

	// Test with timeout parameter
	t.Run("With Timeout", func(t *testing.T) {
		inputObj := struct {
			Command string `json:"command"`
			Timeout string `json:"timeout"`
		}{
			Command: "sleep 0.1 && echo 'Completed'",
			Timeout: "5s",
		}
		inputJSON, err := json.Marshal(inputObj)
		if err != nil {
			t.Fatalf("Failed to marshal input: %v", err)
		}

		result, err := BashRun(context.Background(), inputJSON)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		expected := "Completed\n"
		resultStr := ContentToString(result)
		if resultStr != expected {
			t.Errorf("Expected %q, got %q", expected, resultStr)
		}
	})

	// Test command timeout
	t.Run("Command Timeout", func(t *testing.T) {
		inputObj := struct {
			Command string `json:"command"`
			Timeout string `json:"timeout"`
		}{
			Command: "sleep 0.5 && echo 'Should not see this'",
			Timeout: "100ms",
		}
		inputJSON, err := json.Marshal(inputObj)
		if err != nil {
			t.Fatalf("Failed to marshal input: %v", err)
		}

		_, err = BashRun(context.Background(), inputJSON)
		if err == nil {
			t.Errorf("Expected timeout error, got none")
		} else if !strings.Contains(err.Error(), "timed out") {
			t.Errorf("Expected timeout error, got: %v", err)
		}
	})

	// Test command that fails
	t.Run("Failed Command", func(t *testing.T) {
		input := json.RawMessage(`{"command":"exit 1"}`)

		_, err := BashRun(context.Background(), input)
		if err == nil {
			t.Errorf("Expected error for failed command, got none")
		}
	})

	// Test invalid input
	t.Run("Invalid JSON Input", func(t *testing.T) {
		input := json.RawMessage(`{"command":123}`) // Invalid JSON (command must be string)

		_, err := BashRun(context.Background(), input)
		if err == nil {
			t.Errorf("Expected error for invalid input, got none")
		}
	})
}

func TestExecuteBash(t *testing.T) {
	ctx := context.Background()

	// Test successful command
	t.Run("Successful Command", func(t *testing.T) {
		req := bashInput{
			Command: "echo 'Success'",
			Timeout: "5s",
		}

		output, err := executeBash(ctx, req)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		want := "Success\n"
		if output != want {
			t.Errorf("Expected %q, got %q", want, output)
		}
	})

	// Test SKETCH=1 environment variable is set
	t.Run("SKETCH Environment Variable", func(t *testing.T) {
		req := bashInput{
			Command: "echo $SKETCH",
			Timeout: "5s",
		}

		output, err := executeBash(ctx, req)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		want := "1\n"
		if output != want {
			t.Errorf("Expected SKETCH=1, got %q", output)
		}
	})

	// Test command with output to stderr
	t.Run("Command with stderr", func(t *testing.T) {
		req := bashInput{
			Command: "echo 'Error message' >&2 && echo 'Success'",
			Timeout: "5s",
		}

		output, err := executeBash(ctx, req)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		want := "Error message\nSuccess\n"
		if output != want {
			t.Errorf("Expected %q, got %q", want, output)
		}
	})

	// Test command that fails with stderr
	t.Run("Failed Command with stderr", func(t *testing.T) {
		req := bashInput{
			Command: "echo 'Error message' >&2 && exit 1",
			Timeout: "5s",
		}

		_, err := executeBash(ctx, req)
		if err == nil {
			t.Errorf("Expected error for failed command, got none")
		} else if !strings.Contains(err.Error(), "Error message") {
			t.Errorf("Expected stderr in error message, got: %v", err)
		}
	})

	// Test timeout
	t.Run("Command Timeout", func(t *testing.T) {
		req := bashInput{
			Command: "sleep 1 && echo 'Should not see this'",
			Timeout: "100ms",
		}

		start := time.Now()
		_, err := executeBash(ctx, req)
		elapsed := time.Since(start)

		// Command should time out after ~100ms, not wait for full 1 second
		if elapsed >= 1*time.Second {
			t.Errorf("Command did not respect timeout, took %v", elapsed)
		}

		if err == nil {
			t.Errorf("Expected timeout error, got none")
		} else if !strings.Contains(err.Error(), "timed out") {
			t.Errorf("Expected timeout error, got: %v", err)
		}
	})
}

func TestBackgroundBash(t *testing.T) {
	// Test basic background execution
	t.Run("Basic Background Command", func(t *testing.T) {
		inputObj := struct {
			Command    string `json:"command"`
			Background bool   `json:"background"`
		}{
			Command:    "echo 'Hello from background' $SKETCH",
			Background: true,
		}
		inputJSON, err := json.Marshal(inputObj)
		if err != nil {
			t.Fatalf("Failed to marshal input: %v", err)
		}

		result, err := BashRun(context.Background(), inputJSON)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		// Parse the returned JSON
		var bgResult BackgroundResult
		resultStr := ContentToString(result)
		if err := json.Unmarshal([]byte(resultStr), &bgResult); err != nil {
			t.Fatalf("Failed to unmarshal background result: %v", err)
		}

		// Verify we got a valid PID
		if bgResult.PID <= 0 {
			t.Errorf("Invalid PID returned: %d", bgResult.PID)
		}

		// Verify output files exist
		if _, err := os.Stat(bgResult.StdoutFile); os.IsNotExist(err) {
			t.Errorf("Stdout file doesn't exist: %s", bgResult.StdoutFile)
		}
		if _, err := os.Stat(bgResult.StderrFile); os.IsNotExist(err) {
			t.Errorf("Stderr file doesn't exist: %s", bgResult.StderrFile)
		}

		// Wait for the command output to be written to file
		waitForFile(t, bgResult.StdoutFile)

		// Check file contents
		stdoutContent, err := os.ReadFile(bgResult.StdoutFile)
		if err != nil {
			t.Fatalf("Failed to read stdout file: %v", err)
		}
		expected := "Hello from background 1\n"
		if string(stdoutContent) != expected {
			t.Errorf("Expected stdout content %q, got %q", expected, string(stdoutContent))
		}

		// Clean up
		os.Remove(bgResult.StdoutFile)
		os.Remove(bgResult.StderrFile)
		os.Remove(filepath.Dir(bgResult.StdoutFile))
	})

	// Test background command with stderr output
	t.Run("Background Command with stderr", func(t *testing.T) {
		inputObj := struct {
			Command    string `json:"command"`
			Background bool   `json:"background"`
		}{
			Command:    "echo 'Output to stdout' && echo 'Output to stderr' >&2",
			Background: true,
		}
		inputJSON, err := json.Marshal(inputObj)
		if err != nil {
			t.Fatalf("Failed to marshal input: %v", err)
		}

		result, err := BashRun(context.Background(), inputJSON)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		// Parse the returned JSON
		var bgResult BackgroundResult
		resultStr := ContentToString(result)
		if err := json.Unmarshal([]byte(resultStr), &bgResult); err != nil {
			t.Fatalf("Failed to unmarshal background result: %v", err)
		}

		// Wait for the command output to be written to files
		waitForFile(t, bgResult.StdoutFile)
		waitForFile(t, bgResult.StderrFile)

		// Check stdout content
		stdoutContent, err := os.ReadFile(bgResult.StdoutFile)
		if err != nil {
			t.Fatalf("Failed to read stdout file: %v", err)
		}
		expectedStdout := "Output to stdout\n"
		if string(stdoutContent) != expectedStdout {
			t.Errorf("Expected stdout content %q, got %q", expectedStdout, string(stdoutContent))
		}

		// Check stderr content
		stderrContent, err := os.ReadFile(bgResult.StderrFile)
		if err != nil {
			t.Fatalf("Failed to read stderr file: %v", err)
		}
		expectedStderr := "Output to stderr\n"
		if string(stderrContent) != expectedStderr {
			t.Errorf("Expected stderr content %q, got %q", expectedStderr, string(stderrContent))
		}

		// Clean up
		os.Remove(bgResult.StdoutFile)
		os.Remove(bgResult.StderrFile)
		os.Remove(filepath.Dir(bgResult.StdoutFile))
	})

	// Test background command running without waiting
	t.Run("Background Command Running", func(t *testing.T) {
		// Create a script that will continue running after we check
		inputObj := struct {
			Command    string `json:"command"`
			Background bool   `json:"background"`
		}{
			Command:    "echo 'Running in background' && sleep 5",
			Background: true,
		}
		inputJSON, err := json.Marshal(inputObj)
		if err != nil {
			t.Fatalf("Failed to marshal input: %v", err)
		}

		// Start the command in the background
		result, err := BashRun(context.Background(), inputJSON)
		if err != nil {
			t.Fatalf("Unexpected error: %v", err)
		}

		// Parse the returned JSON
		var bgResult BackgroundResult
		resultStr := ContentToString(result)
		if err := json.Unmarshal([]byte(resultStr), &bgResult); err != nil {
			t.Fatalf("Failed to unmarshal background result: %v", err)
		}

		// Wait for the command output to be written to file
		waitForFile(t, bgResult.StdoutFile)

		// Check stdout content
		stdoutContent, err := os.ReadFile(bgResult.StdoutFile)
		if err != nil {
			t.Fatalf("Failed to read stdout file: %v", err)
		}
		expectedStdout := "Running in background\n"
		if string(stdoutContent) != expectedStdout {
			t.Errorf("Expected stdout content %q, got %q", expectedStdout, string(stdoutContent))
		}

		// Verify the process is still running
		process, _ := os.FindProcess(bgResult.PID)
		err = process.Signal(syscall.Signal(0))
		if err != nil {
			// Process not running, which is unexpected
			t.Error("Process is not running")
		} else {
			// Expected: process should be running
			t.Log("Process correctly running in background")
			// Kill it for cleanup
			process.Kill()
		}

		// Clean up
		os.Remove(bgResult.StdoutFile)
		os.Remove(bgResult.StderrFile)
		os.Remove(filepath.Dir(bgResult.StdoutFile))
	})
}

func TestBashTimeout(t *testing.T) {
	// Test default timeout values
	t.Run("Default Timeout Values", func(t *testing.T) {
		// Test foreground default timeout
		foreground := bashInput{
			Command:    "echo 'test'",
			Background: false,
		}
		fgTimeout := foreground.timeout()
		expectedFg := 10 * time.Second
		if fgTimeout != expectedFg {
			t.Errorf("Expected foreground default timeout to be %v, got %v", expectedFg, fgTimeout)
		}

		// Test background default timeout
		background := bashInput{
			Command:    "echo 'test'",
			Background: true,
		}
		bgTimeout := background.timeout()
		expectedBg := 10 * time.Minute
		if bgTimeout != expectedBg {
			t.Errorf("Expected background default timeout to be %v, got %v", expectedBg, bgTimeout)
		}

		// Test explicit timeout overrides defaults
		explicit := bashInput{
			Command:    "echo 'test'",
			Background: true,
			Timeout:    "5s",
		}
		explicitTimeout := explicit.timeout()
		expectedExplicit := 5 * time.Second
		if explicitTimeout != expectedExplicit {
			t.Errorf("Expected explicit timeout to be %v, got %v", expectedExplicit, explicitTimeout)
		}
	})
}

// waitForFile waits for a file to exist and be non-empty or times out
func waitForFile(t *testing.T, filepath string) {
	timeout := time.After(5 * time.Second)
	tick := time.NewTicker(10 * time.Millisecond)
	defer tick.Stop()

	for {
		select {
		case <-timeout:
			t.Fatalf("Timed out waiting for file to exist and have contents: %s", filepath)
			return
		case <-tick.C:
			info, err := os.Stat(filepath)
			if err == nil && info.Size() > 0 {
				return // File exists and has content
			}
		}
	}
}

// waitForProcessDeath waits for a process to no longer exist or times out
func waitForProcessDeath(t *testing.T, pid int) {
	timeout := time.After(5 * time.Second)
	tick := time.NewTicker(50 * time.Millisecond)
	defer tick.Stop()

	for {
		select {
		case <-timeout:
			t.Fatalf("Timed out waiting for process %d to exit", pid)
			return
		case <-tick.C:
			process, _ := os.FindProcess(pid)
			err := process.Signal(syscall.Signal(0))
			if err != nil {
				// Process doesn't exist
				return
			}
		}
	}
}
