package catalogapp

import (
	"bytes"
	"context"
	"errors"
	"regexp"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	consumerv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/catalog/consumerv1"
)

func TestCanonicalEffectiveMetadataComponentsUsesGrantCapabilityLimit(t *testing.T) {
	behavior := bytes.Repeat([]byte{'x'}, consumerv1.MaxSemanticResponseBytes+1)
	component := EffectiveMetadataComponent{
		ComponentKind:          consumerv1.EffectiveObjectSearchComponentKind,
		ComponentFormatVersion: 1,
		BusinessKey:            consumerv1.EffectiveObjectSearchComponentBusinessKey,
		ContentDigest:          consumerv1.ComputeEffectiveMetadataComponentDigest(behavior),
		CanonicalBehavior:      behavior,
	}
	if _, err := canonicalEffectiveMetadataComponents(
		[]EffectiveMetadataComponent{component},
		consumerv1.AppMetadataV2CapabilityName,
	); err == nil {
		t.Fatal("V2 accepted an effective metadata component above its published limit")
	}
	if _, err := canonicalEffectiveMetadataComponents(
		[]EffectiveMetadataComponent{component},
		consumerv1.AppMetadataV3CapabilityName,
	); err != nil {
		t.Fatalf("V3 rejected a component inside its published limit: %v", err)
	}
}

func TestOperationEffectiveMetadataCapabilityFailsClosedOnStoredMixedVersions(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()
	operation := Operation{
		OperationID:       "018f0000-0000-7000-9000-000000000001",
		AppInstallationID: "018f0000-0000-7000-9000-000000000002",
		OrgID:             "org-test",
	}
	mock.ExpectBegin()
	mock.ExpectQuery(regexp.QuoteMeta(`SELECT
AuthorizedWorkloadId, CapabilityId, OrgId, AppInstallationId
FROM _System_CatalogConsumerGrant
WHERE OperationId = ?
ORDER BY BINARY AuthorizedWorkloadId, BINARY CapabilityId
FOR UPDATE`)).
		WithArgs(operation.OperationID).
		WillReturnRows(sqlmock.NewRows([]string{
			"AuthorizedWorkloadId", "CapabilityId", "OrgId", "AppInstallationId",
		}).
			AddRow("workload-sfcrm-old", consumerv1.AppMetadataV2CapabilityName,
				operation.OrgID, operation.AppInstallationID).
			AddRow("workload-sfcrm-new", consumerv1.AppMetadataV3CapabilityName,
				operation.OrgID, operation.AppInstallationID))
	mock.ExpectRollback()
	tx, err := db.BeginTx(context.Background(), nil)
	if err != nil {
		t.Fatal(err)
	}
	_, err = operationEffectiveMetadataCapabilityTx(context.Background(), tx, operation)
	if !errors.Is(err, ErrCorrupt) {
		t.Fatalf("mixed stored App metadata grants error = %v, want ErrCorrupt", err)
	}
	_ = tx.Rollback()
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatal(err)
	}
}
