package gitstore

import (
	"context"
	"errors"
	"testing"

	"github.com/pingcap/agent-git-service/internal/tenant"
)

func TestTenantRouterSelectsStoreFromContext(t *testing.T) {
	storeA, err := New(t.TempDir())
	if err != nil {
		t.Fatalf("New A: %v", err)
	}
	storeB, err := New(t.TempDir())
	if err != nil {
		t.Fatalf("New B: %v", err)
	}
	router, err := NewTenantRouter(func(ctx context.Context) (*Store, error) {
		info, err := tenant.Require(ctx)
		if err != nil {
			return nil, err
		}
		switch info.ID {
		case "a":
			return storeA, nil
		case "b":
			return storeB, nil
		default:
			return nil, errors.New("unknown tenant")
		}
	})
	if err != nil {
		t.Fatalf("NewTenantRouter: %v", err)
	}

	ctxA := tenant.WithInfo(context.Background(), tenant.Info{ID: "a", CanonicalBaseURL: "https://a.example"})
	ctxB := tenant.WithInfo(context.Background(), tenant.Info{ID: "b", CanonicalBaseURL: "https://b.example"})
	rootA, err := router.RepoRoot(ctxA)
	if err != nil {
		t.Fatalf("RepoRoot A: %v", err)
	}
	rootB, err := router.RepoRoot(ctxB)
	if err != nil {
		t.Fatalf("RepoRoot B: %v", err)
	}
	if rootA == rootB || rootA != storeA.root || rootB != storeB.root {
		t.Fatalf("resolved roots A=%q B=%q", rootA, rootB)
	}
	if _, err := router.RepoRoot(context.Background()); !errors.Is(err, tenant.ErrRequired) {
		t.Fatalf("missing tenant error = %v, want ErrRequired", err)
	}

	called := false
	err = router.WithRepoLock(context.Background(), "owner/repo", func() error {
		called = true
		return nil
	})
	if !errors.Is(err, tenant.ErrRequired) {
		t.Fatalf("missing-tenant lock error = %v, want ErrRequired", err)
	}
	if called {
		t.Fatal("tenant router invoked locked operation without a tenant")
	}
}

func TestTenantRouterWritesOnlySelectedRoot(t *testing.T) {
	storeA, err := New(t.TempDir())
	if err != nil {
		t.Fatalf("New A: %v", err)
	}
	storeB, err := New(t.TempDir())
	if err != nil {
		t.Fatalf("New B: %v", err)
	}
	router, err := NewTenantRouter(func(ctx context.Context) (*Store, error) {
		info, err := tenant.Require(ctx)
		if err != nil {
			return nil, err
		}
		if info.ID == "a" {
			return storeA, nil
		}
		return storeB, nil
	})
	if err != nil {
		t.Fatalf("NewTenantRouter: %v", err)
	}

	ctxA := tenant.WithInfo(context.Background(), tenant.Info{ID: "a", CanonicalBaseURL: "https://a.example"})
	if err := router.Init(ctxA, "owner/repo", "main", false); err != nil {
		t.Fatalf("Init A: %v", err)
	}
	if !storeA.Exists(context.Background(), "owner/repo") {
		t.Fatal("tenant A repository was not created")
	}
	if storeB.Exists(context.Background(), "owner/repo") {
		t.Fatal("tenant A repository appeared in tenant B root")
	}
}
