package audit

import (
	"context"
	"errors"
	"testing"

	domainrls "github.com/nexuscrm/kernel/pkg/rls"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/models"
)

type historyAuthorityMetadata struct {
	schema *models.ObjectMetadata
}

func (m historyAuthorityMetadata) GetSchema(context.Context, string) *models.ObjectMetadata {
	return m.schema
}

type historyAuthorityPermissions struct {
	err error
}

func (historyAuthorityPermissions) CheckObjectPermissionWithUser(context.Context, string, string, *models.UserSession) bool {
	return true
}

func (historyAuthorityPermissions) BuildRLSResult(context.Context, *models.ObjectMetadata, string, *models.UserSession) *domainrls.Result {
	return &domainrls.Result{Skip: true}
}

func (p historyAuthorityPermissions) CheckFieldVisibilityWithUser(context.Context, string, string, *models.UserSession) (bool, error) {
	return false, p.err
}

func TestQueryHistoryAuthorityFailureIsUnavailableBeforeSQL(t *testing.T) {
	authorityErr := errors.New("permission repository unavailable")
	service := NewHistoryQueryService(
		nil,
		historyAuthorityMetadata{schema: &models.ObjectMetadata{
			APIName: "Account",
			Fields:  []models.FieldMetadata{{APIName: "Name", TrackHistory: true}},
		}},
		historyAuthorityPermissions{err: authorityErr},
		nil,
	)

	result, err := service.QueryHistory(context.Background(), contract.HistoryQueryRequest{
		ParentObjectAPIName: "Account",
		SelectFields:        []string{"Field", "OldValue", "NewValue"},
		ParentID:            "account-1",
	}, &models.UserSession{ID: "user-1", ProfileID: "profile-1"})
	if result != nil {
		t.Fatalf("result = %#v, want no partial history result", result)
	}
	var historyErr *HistoryQueryError
	if !errors.As(err, &historyErr) || historyErr.Kind != HistoryQueryErrorUnavailable {
		t.Fatalf("error = %T %[1]v, want HistoryQueryErrorUnavailable", err)
	}
	if !errors.Is(err, authorityErr) {
		t.Fatalf("error = %v, want wrapped permission authority cause", err)
	}
}
