package flags_test

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/veylant/ia-gateway/internal/flags"
)

// TestMemFlagStore_Set_Get tests basic create and retrieve.
func TestMemFlagStore_Set_Get(t *testing.T) {
	store := flags.NewMemFlagStore()
	ctx := context.Background()

	f, err := store.Set(ctx, "tenant-a", "ner_enabled", true)
	require.NoError(t, err)
	assert.Equal(t, "tenant-a", f.TenantID)
	assert.Equal(t, "ner_enabled", f.Name)
	assert.True(t, f.IsEnabled)

	got, err := store.Get(ctx, "tenant-a", "ner_enabled")
	require.NoError(t, err)
	assert.Equal(t, f.ID, got.ID)
	assert.True(t, got.IsEnabled)
}

// TestMemFlagStore_IsEnabled_TenantOverridesGlobal verifies tenant-specific
// flag takes precedence over global.
func TestMemFlagStore_IsEnabled_TenantOverridesGlobal(t *testing.T) {
	store := flags.NewMemFlagStore()
	ctx := context.Background()

	// Global flag: enabled
	_, err := store.Set(ctx, "", "ner_enabled", true)
	require.NoError(t, err)

	// Tenant-specific: disabled
	_, err = store.Set(ctx, "tenant-a", "ner_enabled", false)
	require.NoError(t, err)

	// Tenant A should see disabled (tenant-specific wins)
	enabled, err := store.IsEnabled(ctx, "tenant-a", "ner_enabled")
	require.NoError(t, err)
	assert.False(t, enabled)

	// Tenant B has no specific flag → falls back to global (enabled)
	enabled, err = store.IsEnabled(ctx, "tenant-b", "ner_enabled")
	require.NoError(t, err)
	assert.True(t, enabled)
}

// TestMemFlagStore_IsEnabled_NotFound returns false (no error) for unknown flag.
func TestMemFlagStore_IsEnabled_NotFound(t *testing.T) {
	store := flags.NewMemFlagStore()
	enabled, err := store.IsEnabled(context.Background(), "tenant-a", "nonexistent")
	require.NoError(t, err)
	assert.False(t, enabled)
}

// TestMemFlagStore_Set_Update tests idempotent upsert behaviour.
func TestMemFlagStore_Set_Update(t *testing.T) {
	store := flags.NewMemFlagStore()
	ctx := context.Background()

	f1, _ := store.Set(ctx, "t1", "flag_x", true)
	f2, err := store.Set(ctx, "t1", "flag_x", false)
	require.NoError(t, err)
	assert.Equal(t, f1.ID, f2.ID, "upsert must not create a new entry")
	assert.False(t, f2.IsEnabled)
}

// TestMemFlagStore_Delete removes a flag and returns ErrNotFound on second delete.
func TestMemFlagStore_Delete(t *testing.T) {
	store := flags.NewMemFlagStore()
	ctx := context.Background()

	_, err := store.Set(ctx, "t1", "to_delete", true)
	require.NoError(t, err)

	err = store.Delete(ctx, "t1", "to_delete")
	require.NoError(t, err)

	err = store.Delete(ctx, "t1", "to_delete")
	assert.ErrorIs(t, err, flags.ErrNotFound)
}
