package runtimeworker

import (
	"context"
	"database/sql"
	"fmt"
	"strings"

	"github.com/nexuscrm/backend/internal/runtimeconfig"
	"github.com/nexuscrm/metadata/catalogsnapshot"
	flowsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/flowv1"
	mutationsemantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/recordmutationv1"
	"github.com/pingcap-inc/nexuscrm-controlplane/catalogread"
)

// resolveScheduledFlowAuthority asks Catalog's released read-only serving
// facade which handler binding is active, requires the stopped-upgrade
// candidate pin to assert that exact receipt, and only then follows its
// content-addressed immutable artifacts. The Worker owns neither Catalog
// selection nor lifecycle writes.
func resolveScheduledFlowAuthority(
	ctx context.Context,
	db *sql.DB,
	store catalogsnapshot.Store,
	scope runtimeconfig.WorkerMetadataScope,
) (catalogsnapshot.RuntimeWorkBinding, *catalogsnapshot.RuntimeMetadataView, error) {
	return resolveMetadataWorkAuthority(
		ctx,
		db,
		store,
		scope,
		"runtime scheduled Flow",
		flowsemantic.CapabilityName,
		catalogsnapshot.ProjectionRecordMutationV1,
	)
}

// resolveBulkIngestAuthority freezes every previously-unbound job to the exact
// stopped-upgrade record-mutation candidate owned by this Worker deployment.
// The binding is assigned by the first claim transaction, before any record
// effect; already-bound jobs keep their original immutable version on retry or
// after a rollout.
func resolveBulkIngestAuthority(
	ctx context.Context,
	db *sql.DB,
	store catalogsnapshot.Store,
	scope runtimeconfig.WorkerMetadataScope,
) (catalogsnapshot.RuntimeWorkBinding, *catalogsnapshot.RuntimeMetadataView, error) {
	return resolveMetadataWorkAuthority(
		ctx,
		db,
		store,
		scope,
		"runtime Bulk ingest",
		mutationsemantic.CapabilityName,
		catalogsnapshot.ProjectionRecordMutationV1,
	)
}

// resolveMetadataWorkAuthority is the one Catalog read path for a discovery
// owner that must freeze new durable work to the deployment's exact candidate.
// Durable retries do not call this path; they reopen the binding stored on the
// row through mutationArtifactBinder.
func resolveMetadataWorkAuthority(
	ctx context.Context,
	db *sql.DB,
	store catalogsnapshot.Store,
	scope runtimeconfig.WorkerMetadataScope,
	owner string,
	runtimeCapabilityID string,
	profile catalogsnapshot.ProjectionProfile,
) (catalogsnapshot.RuntimeWorkBinding, *catalogsnapshot.RuntimeMetadataView, error) {
	if ctx == nil || db == nil || store == nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: Catalog authority closure is incomplete", owner)
	}
	if strings.TrimSpace(scope.AppCapabilityID) == "" {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: App capability selection is required", owner)
	}
	if scope.RuntimeCapabilityID != runtimeCapabilityID {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: role selected the wrong neutral Runtime capability", owner)
	}
	if strings.TrimSpace(scope.ExpectedCompatibilityReceiptDigest) == "" {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: exact compatibility receipt selection is required", owner)
	}

	reader, err := catalogread.New(db)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, err
	}
	capability, err := reader.ReadServingCapability(
		ctx,
		scope.AppInstallationID,
		scope.AppCapabilityID,
	)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: read active Catalog capability: %w", owner, err)
	}
	if capability.Installation.OrgID != scope.OrgID ||
		capability.Installation.AppInstallationID != scope.AppInstallationID ||
		capability.Installation.CatalogRevision == 0 ||
		capability.Binding.OrgID != scope.OrgID ||
		capability.Binding.AppInstallationID != scope.AppInstallationID ||
		capability.Binding.CapabilityID != scope.AppCapabilityID ||
		capability.Binding.AppReleaseDigest != capability.Installation.ActiveReleaseDigest {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: Catalog installation/binding tuple is incomplete or mixed", owner)
	}
	if capability.Binding.CompatibilityReceiptDigest != scope.ExpectedCompatibilityReceiptDigest {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: configured receipt is not the active Catalog binding", owner)
	}

	receiptDigest := catalogsnapshot.Digest(scope.ExpectedCompatibilityReceiptDigest)
	receiptArtifact, err := store.Get(
		ctx,
		catalogsnapshot.ArtifactServingCompatibilityReceipt,
		receiptDigest,
	)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: load compatibility receipt: %w", owner, err)
	}
	receipt, err := catalogsnapshot.OpenServingCompatibilityReceipt(receiptArtifact)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: open compatibility receipt: %w", owner, err)
	}
	if receipt.OrgID() != scope.OrgID ||
		receipt.AppInstallationID() != scope.AppInstallationID ||
		string(receipt.AppReleaseDigest()) != capability.Installation.ActiveReleaseDigest ||
		receipt.AppCapabilityID() != scope.AppCapabilityID ||
		receipt.RuntimeCapabilityID() != runtimeCapabilityID ||
		receipt.WorkloadID() != capability.Binding.WorkloadID ||
		string(receipt.ServiceReleaseDigest()) != capability.Binding.ServiceReleaseDigest ||
		receipt.OwnershipEpoch() != capability.Binding.OwnershipEpoch {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: compatibility receipt disagrees with active Catalog authority", owner)
	}

	snapshotArtifact, err := store.Get(
		ctx,
		catalogsnapshot.ArtifactCatalogSnapshot,
		receipt.CatalogSnapshotDigest(),
	)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: load Catalog snapshot: %w", owner, err)
	}
	snapshot, err := catalogsnapshot.OpenCatalogSnapshot(snapshotArtifact)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: open Catalog snapshot: %w", owner, err)
	}
	viewArtifact, err := store.Get(
		ctx,
		catalogsnapshot.ArtifactRuntimeMetadataView,
		receipt.RuntimeMetadataViewDigest(),
	)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: load Runtime metadata view: %w", owner, err)
	}
	view, err := catalogsnapshot.OpenRuntimeMetadataView(viewArtifact)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: open Runtime metadata view: %w", owner, err)
	}
	if err := view.VerifySource(snapshot); err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: verify immutable source: %w", owner, err)
	}
	if err := view.VerifyCompatibility(catalogsnapshot.Compatibility{
		SchemaGeneration: catalogsnapshot.SchemaGeneration(scope.SchemaGeneration),
		EngineGeneration: catalogsnapshot.EngineGeneration(scope.EngineGeneration),
	}); err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: verify compatibility: %w", owner, err)
	}
	lineage := view.Lineage()
	if snapshot.OrgID() != scope.OrgID ||
		view.OrgID() != scope.OrgID ||
		view.AppInstallationID() != scope.AppInstallationID ||
		view.CapabilityID() != runtimeCapabilityID ||
		view.Profile() != profile ||
		lineage != receipt.Lineage() ||
		uint64(lineage.CatalogRevision) != capability.Installation.CatalogRevision {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, fmt.Errorf("%s: immutable view scope or revision disagrees with active Catalog authority", owner)
	}
	binding, err := catalogsnapshot.RuntimeWorkBindingFromView(view)
	if err != nil {
		return catalogsnapshot.RuntimeWorkBinding{}, nil, err
	}
	return binding, view, nil
}
