package runtime

import (
	"os"
	"testing"
)

// TestDetectHostNetUnsupported_EnvOverrides verifies the explicit env
// overrides win over autodetection (the daemon-info path needs a live
// daemon and is covered by the integration smoke test, not here).
func TestDetectHostNetUnsupported_EnvOverrides(t *testing.T) {
	t.Setenv("PANEL_FORCE_BRIDGE", "1")
	if !detectHostNetUnsupported(nil) {
		t.Fatal("PANEL_FORCE_BRIDGE=1 must force bridge fallback (true)")
	}
	os.Unsetenv("PANEL_FORCE_BRIDGE")

	t.Setenv("PANEL_FORCE_HOST_NET", "1")
	if detectHostNetUnsupported(nil) {
		t.Fatal("PANEL_FORCE_HOST_NET=1 must force host networking (false)")
	}
}

// TestBridgeFallbackPreservesBindings is the load-bearing check: on a
// Docker-Desktop-style daemon, a host-mode module must be converted to
// bridge networking WITH its published port bindings intact (so the
// panel-allocated ports actually reach players), whereas on native Linux
// the same module keeps host mode and drops the meaningless bindings.
//
// It exercises the exact decision block in Create() without a live daemon
// by replicating its inputs.
func TestBridgeFallbackPreservesBindings(t *testing.T) {
	ports := []PortSpec{
		{Proto: "udp", HostPort: 14507, ContainerPort: 14507},
		{Proto: "udp", HostPort: 14508, ContainerPort: 14508},
	}
	exposed, bindings, err := buildPortBindings(ports)
	if err != nil {
		t.Fatalf("buildPortBindings: %v", err)
	}
	if len(bindings) != 2 {
		t.Fatalf("expected 2 published bindings, got %d", len(bindings))
	}

	// Native Linux (hostNetUnsupported=false): host mode kept, bindings dropped.
	r := &DockerRuntime{hostNetUnsupported: false}
	netMode, gotExposed, gotBindings := applyHostNetPolicy(r, "host", exposed, bindings)
	if netMode != "host" {
		t.Errorf("linux: netMode = %q, want host", netMode)
	}
	if gotBindings != nil || gotExposed != nil {
		t.Errorf("linux: expected bindings/exposed dropped for host mode")
	}

	// Docker Desktop (hostNetUnsupported=true): host mode → bridge, bindings kept.
	r = &DockerRuntime{hostNetUnsupported: true}
	netMode, gotExposed, gotBindings = applyHostNetPolicy(r, "host", exposed, bindings)
	if netMode != "" {
		t.Errorf("docker desktop: netMode = %q, want bridge (empty)", netMode)
	}
	if len(gotBindings) != 2 {
		t.Errorf("docker desktop: expected 2 bindings preserved, got %d", len(gotBindings))
	}
	if len(gotExposed) != 2 {
		t.Errorf("docker desktop: expected 2 exposed ports preserved, got %d", len(gotExposed))
	}
}
