package catalogapp

import (
	"context"
	"errors"
	"regexp"
	"strings"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
)

func TestRetainedAdmissionRejectsOrphanArtifactReceipt(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()

	mock.ExpectQuery(regexp.QuoteMeta(`SELECT r.AppId, r.AppReleaseDigest, r.AdmissionKind,
r.AttestationKeyId, r.AttestationDigest, r.AttestationVerifiedAt,
(a.AppId IS NOT NULL) AS HasArtifactReceipt, (s.AppId IS NOT NULL) AS HasSourceReceipt
FROM _System_CatalogAppRelease AS r
LEFT JOIN _System_CatalogAppReleaseArtifactReceipt AS a
ON a.AppId = r.AppId AND a.AppReleaseDigest = r.AppReleaseDigest
LEFT JOIN _System_CatalogAppReleaseSourceReceipt AS s
ON s.AppId = r.AppId AND s.AppReleaseDigest = r.AppReleaseDigest
ORDER BY r.AppId, r.AppReleaseDigest`)).WillReturnRows(sqlmock.NewRows([]string{
		"AppId", "AppReleaseDigest", "AdmissionKind", "AttestationKeyId",
		"AttestationDigest", "AttestationVerifiedAt", "HasArtifactReceipt", "HasSourceReceipt",
	}))
	mock.ExpectQuery(regexp.QuoteMeta(`SELECT a.AppId, a.AppReleaseDigest, r.AdmissionKind
FROM _System_CatalogAppReleaseArtifactReceipt AS a
LEFT JOIN _System_CatalogAppRelease AS r
ON r.AppId = a.AppId AND r.AppReleaseDigest = a.AppReleaseDigest
ORDER BY a.AppId, a.AppReleaseDigest`)).WillReturnRows(
		sqlmock.NewRows([]string{"AppId", "AppReleaseDigest", "AdmissionKind"}).
			AddRow("io.example.app", testDigest("orphan-release"), nil),
	)

	err = verifyRetainedReleaseAdmissions(context.Background(), db)
	if !errors.Is(err, ErrCorrupt) || !strings.Contains(err.Error(), "orphan Catalog AppRelease artifact receipt") {
		t.Fatalf("orphan artifact receipt error = %v", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatal(err)
	}
}
