package persistence

import (
	"context"
	"errors"
	"reflect"
	"testing"

	"github.com/nexuscrm/persistence/layoutroutingsecurity"
	layoutroutingsecurityv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/layoutroutingsecurityv1"
)

func TestLayoutRoutingSecurityCanonicalViewStoreSurvivesHaltedRenameOnTiDB(t *testing.T) {
	db, cleanup := openSessionRepositoryTiDB(t)
	defer cleanup()
	foreignDB, foreignCleanup := openSessionRepositoryTiDB(t)
	defer foreignCleanup()
	ctx := context.Background()

	shadow, err := layoutroutingsecurity.CreateHaltedShadowViewStore(ctx, db)
	if err != nil {
		t.Fatal(err)
	}
	foreignShadow, err := layoutroutingsecurity.CreateHaltedShadowViewStore(ctx, foreignDB)
	if err != nil {
		t.Fatal(err)
	}
	view := integrationRoutingSecurityView()
	tx, err := shadow.BeginTx(ctx, nil)
	if err != nil {
		t.Fatal(err)
	}
	digest, err := tx.StoreCanonicalView(ctx, view)
	if err != nil {
		_ = tx.Rollback()
		t.Fatal(err)
	}
	if err := tx.Commit(); err != nil {
		t.Fatal(err)
	}
	read, err := layoutroutingsecurity.ReadCanonicalView(ctx, shadow, view.OrgID, digest)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(read, view) {
		t.Fatalf("shadow read = %#v, want %#v", read, view)
	}
	if _, err := layoutroutingsecurity.ReadCanonicalView(ctx, foreignShadow, view.OrgID, digest); !errors.Is(err, layoutroutingsecurity.ErrViewNotFound) {
		t.Fatalf("foreign shadow read error = %v, want ErrViewNotFound", err)
	}

	if _, err := db.ExecContext(ctx, `RENAME TABLE
_System_LayoutRoutingSecurityViewV2Shadow TO _System_LayoutRoutingSecurityView`); err != nil {
		t.Fatal(err)
	}
	live, err := layoutroutingsecurity.VerifyLiveViewStore(ctx, db)
	if err != nil {
		t.Fatal(err)
	}
	read, err = layoutroutingsecurity.ReadCanonicalView(ctx, live, view.OrgID, digest)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(read, view) {
		t.Fatalf("live read = %#v, want %#v", read, view)
	}
}

func integrationRoutingSecurityView() layoutroutingsecurityv1.View {
	return layoutroutingsecurityv1.View{
		OrgID:                      "org.example",
		CanonicalizationVersion:    layoutroutingsecurityv1.ViewCanonicalizationVersion,
		KeyGrammarVersion:          layoutroutingsecurityv1.KeyGrammarVersion,
		RoleTopologyGrammarVersion: layoutroutingsecurityv1.RoleTopologyGrammarVersion,
		Profiles: []layoutroutingsecurityv1.ProfileIdentity{{
			Key: layoutroutingsecurityv1.ProfileKey{
				NamespaceID: "catalog.example",
				LocalKey:    "admins",
			},
			ResolvedProfileID: "profile-1",
			State:             layoutroutingsecurityv1.IdentityStateActive,
		}},
		Roles: []layoutroutingsecurityv1.RoleIdentity{{
			Key: layoutroutingsecurityv1.RoleKey{
				NamespaceID: "catalog.example",
				LocalKey:    "admins",
			},
			ResolvedRoleID: "role-1",
			State:          layoutroutingsecurityv1.IdentityStateActive,
		}},
	}
}
