package connector_outboundintent

import (
	"context"
	"errors"
	"testing"
	"time"

	commonv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	outboundintentv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/outboundintentv1"
)

type legacyReadinessSource struct {
	legacyIntentSource
	failure         error
	invalidReceipts bool
	calls           int
}

func (s *legacyReadinessSource) ListPendingOutboundIntents(ctx context.Context, request outboundintentv1.ListRequest) (outboundintentv1.ListResponse, error) {
	s.calls++
	if s.calls == 1 && s.failure != nil {
		return outboundintentv1.ListResponse{}, s.failure
	}
	if s.invalidReceipts {
		return outboundintentv1.ListResponse{}, nil
	}
	return s.legacyIntentSource.ListPendingOutboundIntents(ctx, request)
}

func TestLegacyServiceRequiresRuntimeAuthorityBeforeReadiness(t *testing.T) {
	for _, tc := range []struct {
		name            string
		failure         error
		invalidReceipts bool
	}{
		{"transient_runtime", &commonv1.Failure{Category: commonv1.FailureUnavailable}, false},
		{"forbidden_runtime", &commonv1.Failure{Category: commonv1.FailureForbidden}, false},
		{"invalid_authority_receipts", nil, true},
	} {
		t.Run(tc.name, func(t *testing.T) {
			scope := outboundIntentTestScope()
			source := &legacyReadinessSource{legacyIntentSource: legacyIntentSource{scripted: scriptedIntentSource{intent: outboundIntentTestIntent(scope.CatalogRevision, "accepted", "record"), accepted: true}}, failure: tc.failure, invalidReceipts: tc.invalidReceipts}
			acceptor, _ := NewAcceptor(source, &memoryAcceptStore{}, scope)
			worker, _ := NewWorker(&memoryCommandStore{}, &countingPreparer{}, &scriptedCommitter{}, scope, "worker")
			service, _ := NewService(acceptor, worker)
			ctx, cancel := context.WithTimeout(t.Context(), 2*time.Second)
			defer cancel()
			started := false
			err := service.Run(ctx, func() { started = true; cancel() })
			if tc.name == "transient_runtime" {
				if !started || source.calls != 2 || !errors.Is(err, context.Canceled) {
					t.Fatalf("ready=%t calls=%d err=%v", started, source.calls, err)
				}
			} else if started || source.calls != 1 || err == nil {
				t.Fatalf("invalid Runtime admitted readiness: ready=%t calls=%d err=%v", started, source.calls, err)
			}
		})
	}
}
