// Package tests provides E2E tests for TUI SSH usability testing
package tests

import (
	"strings"
	"testing"
	"time"

	testfixtures "github.com/jfraeys/fetch_ml/tests/fixtures"
)

// TestTUI_SSHBasicConnectivity verifies SSH connection and basic command execution
func TestTUI_SSHBasicConnectivity(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Test basic command execution
	output, err := server.Exec("echo 'SSH connection successful'")
	if err != nil {
		t.Fatalf("Failed to execute command over SSH: %v", err)
	}

	if !strings.Contains(output, "SSH connection successful") {
		t.Errorf("Expected SSH output not found. Got: %s", output)
	}
}

// TestTUI_TERMPropagation verifies TERM variable is propagated correctly
func TestTUI_TERMPropagation(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Check TERM variable
	output, err := server.Exec("echo TERM=$TERM")
	if err != nil {
		t.Fatalf("Failed to check TERM: %v", err)
	}

	// Should have a TERM value set
	if !strings.Contains(output, "TERM=") {
		t.Errorf("TERM not set in SSH session. Got: %s", output)
	}

	t.Logf("TERM value: %s", strings.TrimSpace(output))
}

// TestTUI_CaddyConnectivity verifies TUI can reach API through Caddy
func TestTUI_CaddyConnectivity(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Test API health through Caddy (TUI connects to Caddy on port 80)
	output, err := server.Exec("curl -s http://caddy:80/health")
	if err != nil {
		// Try direct API connection as fallback
		output, err = server.Exec("curl -s http://api-server:9101/health")
		if err != nil {
			t.Skipf("API not reachable from SSH container. Ensure docker-compose services are running: %v", err)
		}
	}

	if !strings.Contains(output, `"status":"healthy"`) && !strings.Contains(output, `healthy`) {
		t.Errorf("API health check failed. Got: %s", output)
	}
}

// TestTUI_WebSocketViaCaddy verifies WebSocket proxy through Caddy works
func TestTUI_WebSocketViaCaddy(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Test WebSocket upgrade works through Caddy
	output, err := server.Exec("curl -i -N -H 'Connection: Upgrade' -H 'Upgrade: websocket' http://caddy:80/ws/status 2>&1 | head -20")
	if err != nil {
		// Direct API test as fallback
		output, err = server.Exec("curl -i -N -H 'Connection: Upgrade' -H 'Upgrade: websocket' http://api-server:9101/ws/status 2>&1 | head -20")
		if err != nil {
			t.Skipf("WebSocket test skipped - services may not be running: %v", err)
		}
	}

	// Should see upgrade headers or connection
	if !strings.Contains(output, "Upgrade") && !strings.Contains(output, "101") {
		t.Logf("WebSocket response: %s", output)
	}
}

// TestTUI_TUIConfigExists verifies TUI config is mounted correctly
func TestTUI_TUIConfigExists(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Check TUI config exists
	output, err := server.Exec("cat /config/.ml/config.toml")
	if err != nil {
		t.Fatalf("TUI config not found in SSH container: %v", err)
	}

	// Verify config content
	requiredFields := []string{"worker_host", "worker_port", "worker_user"}
	for _, field := range requiredFields {
		if !strings.Contains(output, field) {
			t.Errorf("Config missing required field: %s", field)
		}
	}

	t.Logf("TUI config:\n%s", output)
}

// TestTUI_TUIRuns verifies TUI binary executes without errors
func TestTUI_TUIRuns(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Verify TUI binary exists and is executable
	output, err := server.Exec("ls -la /usr/local/bin/tui")
	if err != nil {
		t.Fatalf("TUI binary not found: %v", err)
	}

	if !strings.Contains(output, "tui") {
		t.Errorf("TUI binary not found. Got: %s", output)
	}

	// Test TUI can start (help/version check)
	// Note: Full TUI test requires PTY which is in integration tests
	output, err = server.Exec("file /usr/local/bin/tui")
	if err == nil {
		t.Logf("TUI binary info: %s", strings.TrimSpace(output))
	}
}

// TestTUI_PTYSession tests PTY allocation for interactive TUI
func TestTUI_PTYSession(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Create PTY session
	session, err := server.ExecWithPTY("echo 'PTY test'", "xterm-256color", 80, 24)
	if err != nil {
		t.Skipf("PTY session failed - SSH server may not support PTY: %v", err)
	}
	defer session.Close()

	// Wait for command to complete
	done := make(chan error, 1)
	go func() {
		done <- session.Wait()
	}()

	select {
	case err := <-done:
		if err != nil {
			t.Logf("PTY session completed with error (may be expected): %v", err)
		}
	case <-time.After(5 * time.Second):
		t.Log("PTY session timed out")
	}
}

// TestTUI_TerminfoAvailable verifies terminfo database is available
func TestTUI_TerminfoAvailable(t *testing.T) {
	t.Parallel()

	server := testfixtures.NewSSHTestServer(t)

	// Check for terminfo
	output, err := server.Exec("ls /usr/share/terminfo/x/ | head -5")
	if err != nil {
		t.Logf("terminfo check: %v", err)
	} else {
		t.Logf("Available terminfo entries: %s", strings.TrimSpace(output))
	}

	// Check tput works
	output, err = server.Exec("tput colors 2>/dev/null || echo 'tput not available'")
	t.Logf("Color support: %s", strings.TrimSpace(output))
}
