package rest

import (
	"os"
	"path/filepath"
	"testing"
)

func TestLoadRPCAccessProductsFromRepoDefault(t *testing.T) {
	// The repo ships config/rpc_products.yaml relative to backend/. When
	// running `go test ./...` from the repo root, the loader's relative
	// search path finds it there. Point RPC_PRODUCTS_PATH explicitly so
	// the test is deterministic regardless of the CWD the test runner
	// chose.
	repoRoot, err := findBackendRoot()
	if err != nil {
		t.Fatalf("locate backend root: %v", err)
	}
	t.Setenv("RPC_PRODUCTS_PATH", filepath.Join(repoRoot, "config", "rpc_products.yaml"))

	products, path, err := loadRPCAccessProducts()
	if err != nil {
		t.Fatalf("loadRPCAccessProducts: %v", err)
	}
	if path == "" {
		t.Fatalf("loadRPCAccessProducts returned empty path")
	}
	if len(products) < 3 {
		t.Fatalf("expected at least 3 products, got %d", len(products))
	}

	slugs := map[string]bool{}
	for _, p := range products {
		slugs[p.Slug] = true
		if p.HTTPURL == "" {
			t.Errorf("product %q has empty http_url", p.Slug)
		}
	}
	for _, required := range []string{"core-rpc", "alltra-rpc", "thirdweb-rpc"} {
		if !slugs[required] {
			t.Errorf("expected product slug %q in catalog", required)
		}
	}
}

func TestLoadRPCAccessProductsRejectsDuplicateSlug(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "rpc_products.yaml")
	yaml := `products:
  - slug: a
    http_url: https://a.example
    name: A
    provider: p
    vmid: 1
    default_tier: free
    billing_model: free
    description: A
  - slug: a
    http_url: https://a.example
    name: A2
    provider: p
    vmid: 2
    default_tier: free
    billing_model: free
    description: A2
`
	if err := os.WriteFile(path, []byte(yaml), 0o600); err != nil {
		t.Fatalf("write fixture: %v", err)
	}
	t.Setenv("RPC_PRODUCTS_PATH", path)

	if _, _, err := loadRPCAccessProducts(); err == nil {
		t.Fatal("expected duplicate-slug error, got nil")
	}
}

func TestLoadRPCAccessProductsRejectsMissingHTTPURL(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "rpc_products.yaml")
	if err := os.WriteFile(path, []byte("products:\n  - slug: x\n    name: X\n"), 0o600); err != nil {
		t.Fatalf("write fixture: %v", err)
	}
	t.Setenv("RPC_PRODUCTS_PATH", path)

	if _, _, err := loadRPCAccessProducts(); err == nil {
		t.Fatal("expected missing-http_url error, got nil")
	}
}

// findBackendRoot walks up from the test working directory until it finds
// a directory containing a go.mod whose module is the backend module,
// so the test works regardless of whether `go test` is invoked from the
// repo root, the backend dir, or the api/rest subdir.
func findBackendRoot() (string, error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	for {
		goMod := filepath.Join(cwd, "go.mod")
		if _, err := os.Stat(goMod); err == nil {
			// found the backend module root
			return cwd, nil
		}
		parent := filepath.Dir(cwd)
		if parent == cwd {
			return "", os.ErrNotExist
		}
		cwd = parent
	}
}
