package host

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"
)

func TestWSLBackendIntegration(t *testing.T) {
	distro := os.Getenv("WSL_DISTRO")
	if distro == "" {
		t.Skip("WSL_DISTRO not set, skipping WSL integration test (set WSL_DISTRO=cyrene-wsl to run)")
	}

	backend := NewWSLBackend(distro, "cyrene", "test123", 30*time.Second)
	mgr := NewManager(backend)
	ctx := context.Background()

	// 1. Basic command
	t.Run("echo", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "echo 'hello from WSL OS env'", "", 10*time.Second)
		if err != nil {
			t.Fatalf("exec failed: %v", err)
		}
		if r.ExitCode != 0 {
			t.Fatalf("exit=%d, stderr=%s", r.ExitCode, r.Stderr)
		}
		if !strings.Contains(r.Stdout, "hello from WSL OS env") {
			t.Fatalf("unexpected stdout: %s", r.Stdout)
		}
		t.Logf("echo OK: %s (duration=%s)", strings.TrimSpace(r.Stdout), r.Duration)
	})

	// 2. Complex commands - package manager
	t.Run("apt", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "apt --version 2>&1", "", 10*time.Second)
		if err != nil {
			t.Fatalf("exec failed: %v", err)
		}
		t.Logf("apt OK: %s", strings.TrimSpace(r.Stdout))
	})

	// 3. Python (should be pre-installed on Ubuntu)
	t.Run("python", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "python3 --version 2>&1", "", 10*time.Second)
		if err != nil {
			t.Fatalf("exec failed: %v", err)
		}
		t.Logf("python OK: %s", strings.TrimSpace(r.Stdout))
	})

	// 4. Pipeline & shell features
	t.Run("pipeline", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "echo 'a\nb\nc\nd' | wc -l", "", 10*time.Second)
		if err != nil {
			t.Fatalf("exec failed: %v", err)
		}
		if r.ExitCode != 0 {
			t.Fatalf("exit=%d", r.ExitCode)
		}
		t.Logf("pipeline OK: %s", strings.TrimSpace(r.Stdout))
	})

	// 5. File write & read
	t.Run("file_rw", func(t *testing.T) {
		err := mgr.WriteFile("/tmp/cyrene-wsl-test.txt", "Hello from Cyrene OS!", 1024*1024)
		if err != nil {
			t.Fatalf("write failed: %v", err)
		}
		content, err := mgr.ReadFile("/tmp/cyrene-wsl-test.txt", 1024*1024)
		if err != nil {
			t.Fatalf("read failed: %v", err)
		}
		if content != "Hello from Cyrene OS!" {
			t.Fatalf("content mismatch: %q", content)
		}
		t.Logf("file r/w OK: %q", content)
	})

	// 6. Directory listing
	t.Run("listdir", func(t *testing.T) {
		entries, err := mgr.ListDir("/etc")
		if err != nil {
			t.Fatalf("listdir failed: %v", err)
		}
		if len(entries) == 0 {
			t.Fatal("expected entries in /etc")
		}
		t.Logf("listdir OK: %d entries in /etc", len(entries))
		for _, e := range entries {
			if e.Name == "os-release" || e.Name == "hostname" {
				t.Logf("  - %s (isDir=%v, size=%d)", e.Name, e.IsDir, e.Size)
			}
		}
	})

	// 7. System info
	t.Run("sysinfo", func(t *testing.T) {
		info := mgr.SystemInfo()
		if info["backend"] != "wsl" {
			t.Fatalf("unexpected backend: %v", info["backend"])
		}
		if info["distro"] != distro {
			t.Fatalf("unexpected distro: %v", info["distro"])
		}
		t.Logf("sysinfo OK: backend=%v, distro=%v", info["backend"], info["distro"])
		if uname, ok := info["uname"]; ok {
			t.Logf("  uname: %v", uname)
		}
		if hostname, ok := info["hostname"]; ok {
			t.Logf("  hostname: %v", hostname)
		}
		if mem, ok := info["memory"]; ok {
			t.Logf("  memory: %v", mem)
		}
	})

	// 8. workDir
	t.Run("workdir", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "pwd", "/tmp", 10*time.Second)
		if err != nil {
			t.Fatalf("exec failed: %v", err)
		}
		if !strings.Contains(r.Stdout, "/tmp") {
			t.Fatalf("expected /tmp, got: %s", r.Stdout)
		}
		t.Logf("workdir OK: pwd=%s", strings.TrimSpace(r.Stdout))
	})

	// 9. Timeout
	t.Run("timeout", func(t *testing.T) {
		r, err := mgr.Exec(ctx, "sleep 10", "", 1*time.Second)
		if err == nil {
			t.Fatal("expected timeout")
		}
		if !r.TimedOut {
			t.Fatal("expected TimedOut=true")
		}
		t.Logf("timeout OK: timed_out=%v", r.TimedOut)
	})
}
