package integrationservice

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"time"

	connectorserving "github.com/pingcap-inc/nexuscrm-connectors/features/connector/serving"
)

// isolatedExecutionConformance is the non-production composition boundary for
// the Connector V2 walking slice. AssembleProduction must not construct or run
// it before the separately proved whole-service activation.
type isolatedExecutionConformance struct {
	repository *connectorserving.ExecutionRepository
	reconciler *connectorserving.ConformanceExecutionReconciler
}

func newIsolatedExecutionConformance(
	ctx context.Context,
	db *sql.DB,
	runtime connectorserving.ExecutionRuntimeClient,
) (*isolatedExecutionConformance, error) {
	if ctx == nil {
		return nil, errors.New("integration service: V2 execution conformance context is required")
	}
	if db == nil || runtime == nil {
		return nil, errors.New("integration service: V2 execution conformance dependencies are required")
	}
	repository, err := connectorserving.NewExecutionRepository(db)
	if err != nil {
		return nil, fmt.Errorf("integration service: build V2 execution repository: %w", err)
	}
	if err := repository.VerifySchema(ctx); err != nil {
		return nil, fmt.Errorf("integration service: verify V2 execution schema: %w", err)
	}
	reconciler, err := connectorserving.NewConformanceExecutionReconciler(repository, runtime)
	if err != nil {
		return nil, fmt.Errorf("integration service: build V2 execution reconciler: %w", err)
	}
	return &isolatedExecutionConformance{repository: repository, reconciler: reconciler}, nil
}

func (composition *isolatedExecutionConformance) Admit(
	ctx context.Context,
	candidate connectorserving.ConformanceExecutionCandidate,
) (connectorserving.Execution, bool, error) {
	if composition == nil || composition.repository == nil {
		return connectorserving.Execution{}, false, errors.New(
			"integration service: V2 execution conformance repository is unavailable",
		)
	}
	return composition.repository.AdmitConformance(ctx, candidate)
}

func (composition *isolatedExecutionConformance) Reconcile(
	ctx context.Context,
	executionID string,
	holderID string,
	lease time.Duration,
) (connectorserving.Execution, error) {
	if composition == nil || composition.reconciler == nil {
		return connectorserving.Execution{}, errors.New(
			"integration service: V2 execution conformance reconciler is unavailable",
		)
	}
	return composition.reconciler.Reconcile(ctx, executionID, holderID, lease)
}
