package bootstrapimpl

import (
	"context"
	"database/sql"

	database "github.com/nexuscrm/db"
	"github.com/nexuscrm/db/pkg/runtimeports"
	"github.com/nexuscrm/db/pkg/schemashape"
	"github.com/nexuscrm/kernel/pkg/schema"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/assertion"
)

// SchemaProvisionerImpl is the concrete runtimeports.SchemaProvisioner. It
// delegates each method to the canonical bootstrap function of the same name.
// It carries no logic and no state of its own: behavior is byte-for-byte
// identical to calling the bootstrap function directly. Each wrapped function
// mutates the database, so its per-call *sql.DB / *database.TiDBConnection /
// context.Context argument is preserved exactly; the struct binds no per-call
// dependency and is safe to construct at package init.
//
// The port interface lives in pkg/serverruntime/runtimeports (a leaf package
// that imports nothing backend-internal). bootstrap is allowed to import
// runtimeports, so the concrete impl is hosted here next to the functions it
// wraps. The runtime composition root (pkg/serverruntime) constructs this and
// injects it into the control-plane consumers, which depend only on the port.
type SchemaProvisionerImpl struct{}

// NewSchemaProvisionerImpl returns a SchemaProvisionerImpl. Intended for
// composition-root wiring.
func NewSchemaProvisionerImpl() SchemaProvisionerImpl {
	return SchemaProvisionerImpl{}
}

// Compile-time assertion that the bootstrap impl satisfies the runtimeports port.
var _ runtimeports.SchemaProvisioner = SchemaProvisionerImpl{}

// InitializeSchema delegates to bootstrap.InitializeSchema.
func (SchemaProvisionerImpl) InitializeSchema(db *database.TiDBConnection) error {
	return InitializeSchema(db)
}

// InitializeSchemaL0 delegates to bootstrap.InitializeSchemaL0.
func (SchemaProvisionerImpl) InitializeSchemaL0(db *database.TiDBConnection) error {
	return InitializeSchemaL0(db)
}

// EnsureL0SchemaDDL delegates to bootstrap.EnsureL0SchemaDDL.
func (SchemaProvisionerImpl) EnsureL0SchemaDDL(db *database.TiDBConnection) error {
	return EnsureL0SchemaDDL(db)
}

// ReconcileTableColumns delegates to bootstrap.ReconcileTableColumns.
func (SchemaProvisionerImpl) ReconcileTableColumns(rawDB *sql.DB, tableDefs []schema.TableDefinition) error {
	return ReconcileTableColumns(rawDB, tableDefs)
}

// ReconcileSystemObjectTableColumns delegates to bootstrap.ReconcileSystemObjectTableColumns.
func (SchemaProvisionerImpl) ReconcileSystemObjectTableColumns(rawDB *sql.DB) error {
	return ReconcileSystemObjectTableColumns(rawDB)
}

// ReconcileSystemObjectTableTypes delegates to bootstrap.ReconcileSystemObjectTableTypes.
func (SchemaProvisionerImpl) ReconcileSystemObjectTableTypes(ctx context.Context, db *sql.DB) error {
	return ReconcileSystemObjectTableTypes(ctx, db)
}

// EnsureStandardIndexes delegates to bootstrap.EnsureStandardIndexes.
func (SchemaProvisionerImpl) EnsureStandardIndexes(dbInstance *database.TiDBConnection) error {
	return EnsureStandardIndexes(dbInstance)
}

// DiscoverAndRegisterPhysicalTables delegates to bootstrap.DiscoverAndRegisterPhysicalTables.
func (SchemaProvisionerImpl) DiscoverAndRegisterPhysicalTables(dbInstance *database.TiDBConnection) error {
	return DiscoverAndRegisterPhysicalTables(dbInstance)
}

// RunAssertions delegates to bootstrap.RunAssertions.
func (SchemaProvisionerImpl) RunAssertions(db *database.TiDBConnection, strictMode bool) (*assertion.AssertionResult, error) {
	return RunAssertions(db, strictMode)
}

// RunPodReadinessAssertions delegates to the startup-safe strict assertion
// path, which accepts only the fully absent connected-delivery prior state.
func (SchemaProvisionerImpl) RunPodReadinessAssertions(db *database.TiDBConnection) error {
	_, err := RunPodReadinessAssertions(db)
	return err
}

// EnsureFolderSharingModels delegates to bootstrap.EnsureFolderSharingModels.
func (SchemaProvisionerImpl) EnsureFolderSharingModels(ctx context.Context, db *sql.DB) error {
	return EnsureFolderSharingModels(ctx, db)
}

// DropGroupMemberUserFK delegates to bootstrap.DropGroupMemberUserFK.
func (SchemaProvisionerImpl) DropGroupMemberUserFK(ctx context.Context, db *sql.DB) error {
	return DropGroupMemberUserFK(ctx, db)
}

// NormalizeLegacyDDLDefaults delegates to bootstrap.NormalizeLegacyDDLDefaults.
func (SchemaProvisionerImpl) NormalizeLegacyDDLDefaults(ctx context.Context, dbConn *database.TiDBConnection) error {
	return NormalizeLegacyDDLDefaults(ctx, dbConn)
}

// BackfillFieldCapabilities delegates to bootstrap.BackfillFieldCapabilities.
func (SchemaProvisionerImpl) BackfillFieldCapabilities(dbConn *database.TiDBConnection) error {
	return BackfillFieldCapabilities(dbConn)
}

// VerifySchemaReadiness delegates to bootstrap.VerifySchemaReadiness.
func (SchemaProvisionerImpl) VerifySchemaReadiness(db *database.TiDBConnection) error {
	return VerifySchemaReadiness(db)
}

// VerifyConnectedDeliverySchema delegates to the operator-facing connected
// delivery exact-convergence check. This is intentionally separate from
// VerifySchemaReadiness so dormant schema does not gate pod startup.
func (SchemaProvisionerImpl) VerifyConnectedDeliverySchema(db *database.TiDBConnection) error {
	return VerifyConnectedDeliverySchema(db)
}

// LoadPhysicalColumnShapes delegates to bootstrap.LoadPhysicalColumnShapes.
func (SchemaProvisionerImpl) LoadPhysicalColumnShapes(rawDB *sql.DB) (map[string]map[string]schemashape.PhysicalColumnShape, error) {
	return LoadPhysicalColumnShapes(rawDB)
}

// DesiredColumnType delegates to bootstrap.DesiredColumnType.
func (SchemaProvisionerImpl) DesiredColumnType(col schema.ColumnDefinition) string {
	return DesiredColumnType(col)
}

// ColumnShapeMatches delegates to bootstrap.ColumnShapeMatches.
func (SchemaProvisionerImpl) ColumnShapeMatches(existing schemashape.PhysicalColumnShape, desired schema.ColumnDefinition) bool {
	return ColumnShapeMatches(existing, desired)
}

// ColumnShapeMatchesForTable delegates to the managed-table-aware physical
// compatibility matcher. It is an optional extension to the neutral
// SchemaProvisioner port so existing implementations remain source-compatible.
func (SchemaProvisionerImpl) ColumnShapeMatchesForTable(tableName string, existing schemashape.PhysicalColumnShape, desired schema.ColumnDefinition) bool {
	return ColumnShapeMatchesForTable(tableName, existing, desired)
}

// ReconcileManagedStandardObjectAccessPoliciesWithDefs delegates to
// bootstrap.ReconcileManagedStandardObjectAccessPoliciesWithDefs.
func (SchemaProvisionerImpl) ReconcileManagedStandardObjectAccessPoliciesWithDefs(rawDB *sql.DB, tableDefs []schema.TableDefinition) error {
	return ReconcileManagedStandardObjectAccessPoliciesWithDefs(rawDB, tableDefs)
}

// AssertManagedAccessPolicyConsistency delegates to
// bootstrap.AssertManagedAccessPolicyConsistency.
func (SchemaProvisionerImpl) AssertManagedAccessPolicyConsistency(db *sql.DB, result *assertion.AssertionResult, managedPolicies map[string]schema.ManagedStandardObjectPolicy) {
	AssertManagedAccessPolicyConsistency(db, result, managedPolicies)
}

// AssertManagedRelationshipConsistency delegates to
// bootstrap.AssertManagedRelationshipConsistency.
func (SchemaProvisionerImpl) AssertManagedRelationshipConsistency(db *sql.DB, result *assertion.AssertionResult, defs []schema.ManagedRelationshipSemantics, tableDefs ...[]schema.TableDefinition) {
	AssertManagedRelationshipConsistency(db, result, defs, tableDefs...)
}

// BuildManagedRelationshipFieldMetadata delegates to
// bootstrap.BuildManagedRelationshipFieldMetadata.
func (SchemaProvisionerImpl) BuildManagedRelationshipFieldMetadata(tableDefs []schema.TableDefinition) map[string]runtimeports.ManagedRelationshipFieldMetadata {
	return BuildManagedRelationshipFieldMetadata(tableDefs)
}

// ManagedRelationshipKey delegates to bootstrap.ManagedRelationshipKey.
func (SchemaProvisionerImpl) ManagedRelationshipKey(childObjectAPIName, parentObjectAPIName, fieldAPIName string) string {
	return ManagedRelationshipKey(childObjectAPIName, parentObjectAPIName, fieldAPIName)
}

// NeedsOverlayRow delegates to bootstrap.NeedsOverlayRow.
func (SchemaProvisionerImpl) NeedsOverlayRow(meta runtimeports.ManagedRelationshipFieldMetadata, def schema.ManagedRelationshipSemantics) bool {
	return NeedsOverlayRow(meta, def)
}

// LookupReferenceRepairTargets delegates to bootstrap.LookupReferenceRepairTargets.
func (SchemaProvisionerImpl) LookupReferenceRepairTargets() runtimeports.LookupReferenceTargets {
	return LookupReferenceRepairTargets()
}
