package sidecarchan

import (
	"path/filepath"
	"testing"
)

func TestFromEnv_DefaultIsNilChannel(t *testing.T) {
	getenv := func(k string) string { return "" }
	ch, err := FromEnv(getenv, t.TempDir())
	if err != nil {
		t.Fatal(err)
	}
	if ch != nil {
		t.Errorf("default mode should yield nil channel (pane scraping), got %T", ch)
	}
}

func TestFromEnv_PaneExplicitIsNilChannel(t *testing.T) {
	getenv := func(k string) string {
		if k == "HARNESS_SIDECAR_CHANNEL" {
			return "pane"
		}
		return ""
	}
	ch, err := FromEnv(getenv, t.TempDir())
	if err != nil {
		t.Fatal(err)
	}
	if ch != nil {
		t.Errorf("pane mode should yield nil channel, got %T", ch)
	}
}

func TestFromEnv_SocketReturnsSocketChannel(t *testing.T) {
	dir := shortTempDir(t)
	getenv := func(k string) string {
		if k == "HARNESS_SIDECAR_CHANNEL" {
			return "socket"
		}
		return ""
	}
	ch, err := FromEnv(getenv, dir)
	if err != nil {
		t.Fatal(err)
	}
	sc, ok := ch.(*SocketChannel)
	if !ok {
		t.Fatalf("want *SocketChannel, got %T", ch)
	}
	// Open should bind a socket under dir.
	info, err := sc.Open("a")
	if err != nil {
		t.Fatal(err)
	}
	if !pathHasPrefix(info.Env["HARNESS_SEND_SOCKET"], dir) {
		t.Errorf("socket path %q not under base %q", info.Env["HARNESS_SEND_SOCKET"], dir)
	}
	sc.CloseAll()
}

func TestFromEnv_MailboxReturnsMailboxChannel(t *testing.T) {
	dir := t.TempDir()
	getenv := func(k string) string {
		if k == "HARNESS_SIDECAR_CHANNEL" {
			return "mailbox"
		}
		return ""
	}
	ch, err := FromEnv(getenv, dir)
	if err != nil {
		t.Fatal(err)
	}
	mc, ok := ch.(*MailboxChannel)
	if !ok {
		t.Fatalf("want *MailboxChannel, got %T", ch)
	}
	info, err := mc.Open("a")
	if err != nil {
		t.Fatal(err)
	}
	if !pathHasPrefix(info.Env["HARNESS_MAILBOX_PATH"], dir) {
		t.Errorf("mailbox path %q not under base %q", info.Env["HARNESS_MAILBOX_PATH"], dir)
	}
	mc.CloseAll()
}

func TestFromEnv_UnknownModeIsError(t *testing.T) {
	getenv := func(k string) string {
		if k == "HARNESS_SIDECAR_CHANNEL" {
			return "totally-bogus"
		}
		return ""
	}
	if _, err := FromEnv(getenv, t.TempDir()); err == nil {
		t.Fatal("expected error on unknown channel mode")
	}
}

func TestFromEnv_RespectsBaseDirOverride(t *testing.T) {
	// HARNESS_SIDECAR_BASEDIR overrides the default base.
	override := shortTempDir(t)
	defaultBase := t.TempDir()
	getenv := func(k string) string {
		switch k {
		case "HARNESS_SIDECAR_CHANNEL":
			return "socket"
		case "HARNESS_SIDECAR_BASEDIR":
			return override
		}
		return ""
	}
	ch, err := FromEnv(getenv, defaultBase)
	if err != nil {
		t.Fatal(err)
	}
	sc := ch.(*SocketChannel)
	info, err := sc.Open("a")
	if err != nil {
		t.Fatal(err)
	}
	if !pathHasPrefix(info.Env["HARNESS_SEND_SOCKET"], override) {
		t.Errorf("override base ignored: got %q, want under %q", info.Env["HARNESS_SEND_SOCKET"], override)
	}
	sc.CloseAll()
}

func pathHasPrefix(p, prefix string) bool {
	abs, _ := filepath.Abs(p)
	absPrefix, _ := filepath.Abs(prefix)
	if len(abs) < len(absPrefix) {
		return false
	}
	return abs[:len(absPrefix)] == absPrefix
}
