package epics_test

import (
	"context"
	"os"
	"testing"
	"time"

	"github.com/uopi/goca/proto"
	"github.com/uopi/goca/testca"
	"github.com/uopi/uopi/internal/datasource/epics"
)

func TestDiscovery_EnvironmentVariables(t *testing.T) {
	// 1. Setup a fake CA server.
	srv, err := testca.New([]testca.PVSpec{
		{Name: "DISCO:PV", DBFType: proto.DBFDouble, Count: 1, Value: 123.45},
	})
	if err != nil {
		t.Fatalf("testca.New: %v", err)
	}
	defer srv.Close()

	// 2. Set the environment variable to point to this server.
	os.Setenv("EPICS_CA_ADDR_LIST", srv.UDPAddr())
	os.Setenv("EPICS_CA_AUTO_ADDR_LIST", "NO")
	defer os.Unsetenv("EPICS_CA_ADDR_LIST")
	defer os.Unsetenv("EPICS_CA_AUTO_ADDR_LIST")

	// 3. Create datasource with NO explicit address (should pick up from env).
	ds := epics.New("", "", "", "", false, nil)
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := ds.Connect(ctx); err != nil {
		t.Fatalf("Connect: %v", err)
	}

	// 4. Verify discovery works.
	meta, err := ds.GetMetadata(ctx, "DISCO:PV")
	if err != nil {
		t.Fatalf("GetMetadata failed (discovery failed): %v", err)
	}
	if meta.Name != "DISCO:PV" {
		t.Errorf("got %q, want DISCO:PV", meta.Name)
	}
}

func TestDiscovery_ConfigOverride(t *testing.T) {
	// 1. Setup TWO fake CA servers.
	srv1, _ := testca.New([]testca.PVSpec{{Name: "PV:1", DBFType: proto.DBFDouble, Value: 1.0}})
	defer srv1.Close()
	srv2, _ := testca.New([]testca.PVSpec{{Name: "PV:2", DBFType: proto.DBFDouble, Value: 2.0}})
	defer srv2.Close()

	// 2. Point env to srv1.
	os.Setenv("EPICS_CA_ADDR_LIST", srv1.UDPAddr())
	os.Setenv("EPICS_CA_AUTO_ADDR_LIST", "NO")
	defer os.Unsetenv("EPICS_CA_ADDR_LIST")
	defer os.Unsetenv("EPICS_CA_AUTO_ADDR_LIST")

	// 3. Create datasource pointing explicitly to srv2 (should OVERRIDE env).
	ds := epics.New(srv2.UDPAddr(), "", "", "", false, nil)
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := ds.Connect(ctx); err != nil {
		t.Fatalf("Connect: %v", err)
	}

	// 4. PV from srv2 should be found.
	if _, err := ds.GetMetadata(ctx, "PV:2"); err != nil {
		t.Errorf("PV:2 from config address not found: %v", err)
	}

	// 5. PV from srv1 should NOT be found (since AutoAddrList is disabled by config override).
	ctx2, cancel2 := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel2()
	if _, err := ds.GetMetadata(ctx2, "PV:1"); err == nil {
		t.Error("PV:1 from env address was found, but config should have overridden it")
	}
}
