package main

import (
	"encoding/binary"
	"os"
	"strings"
	"testing"
)

func skipIfNoDocker(t *testing.T) {
	t.Helper()
	if _, err := os.Stat(dockerSocketPath); err != nil {
		t.Skipf("docker socket %s not accessible", dockerSocketPath)
	}
}

func TestDockerList_Live(t *testing.T) {
	skipIfNoDocker(t)
	cap := &Capability{Name: "docker.container.list"}
	res, code, err := runDockerList(cap, map[string]any{"all": true})
	if err != nil {
		t.Fatalf("list: %v", err)
	}
	if code != 0 {
		t.Fatalf("expected code=0 got %d", code)
	}
	m := res.(map[string]any)
	if _, ok := m["containers"]; !ok {
		t.Fatalf("missing containers in result")
	}
}

func TestDockerExec_BinaryNotAllowed(t *testing.T) {
	cap := &Capability{
		Name:            "docker.container.exec",
		BinariesAllowed: []string{"ls"},
	}
	_, _, err := runDockerExec(cap, map[string]any{
		"container": "any",
		"argv":      []any{"rm", "-rf", "/"},
	})
	if err == nil || !strings.Contains(err.Error(), "whitelist") {
		t.Fatalf("expected whitelist reject, got %v", err)
	}
}

func TestDockerExec_NoArgv(t *testing.T) {
	cap := &Capability{Name: "docker.container.exec", BinariesAllowed: []string{"ls"}}
	_, _, err := runDockerExec(cap, map[string]any{"container": "x"})
	if err == nil || !strings.Contains(err.Error(), "argv required") {
		t.Fatalf("expected argv required, got %v", err)
	}
}

func TestDemuxDockerStream(t *testing.T) {
	// Construir un frame stdout "hello" + stderr "err"
	mk := func(typ byte, payload string) []byte {
		hdr := make([]byte, 8)
		hdr[0] = typ
		binary.BigEndian.PutUint32(hdr[4:], uint32(len(payload)))
		return append(hdr, []byte(payload)...)
	}
	stream := append(mk(1, "hello"), mk(2, "err")...)
	so, se := demuxDockerStream(stream)
	if so != "hello" || se != "err" {
		t.Fatalf("demux failed: stdout=%q stderr=%q", so, se)
	}
}

func TestDockerLogs_NoContainer(t *testing.T) {
	cap := &Capability{Name: "docker.container.logs"}
	_, _, err := runDockerLogs(cap, map[string]any{})
	if err == nil || !strings.Contains(err.Error(), "container required") {
		t.Fatalf("expected container required, got %v", err)
	}
}
