package controlplane

import (
	"context"
	"strings"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/nexuscrm/db"
	"github.com/pingcap-inc/nexuscrm-controlplane/packs"
)

func TestVerifyInstalledAppPacksRejectsInvalidFrozenFormulaPayload(t *testing.T) {
	root := writeFrozenFormulaSourceRoot(t, `BLANKVALUE(Subject, "n/a")`)

	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	defer db.Close()

	expectInstalledPackRuntimeDeclarationColumns(mock, false)
	mock.ExpectQuery("SELECT Name, Category, Status, PackVersion, ManifestFormatVersion, PlatformCompatibility, DesiredPayloadHash, AppliedPayloadHash, PayloadHashAlgorithm, SourceKind, SourceURI, SourceRevision").
		WithArgs(string(packs.AppPack), string(packs.ConnectorPack)).
		WillReturnRows(sqlmock.NewRows([]string{
			"Name", "Category", "Status", "PackVersion", "ManifestFormatVersion", "PlatformCompatibility",
			"DesiredPayloadHash", "AppliedPayloadHash", "PayloadHashAlgorithm", "SourceKind", "SourceURI", "SourceRevision", "HostRequirementsDigest",
		}).AddRow(
			"jira-like-sample",
			string(packs.AppPack),
			installedPackStatusActive,
			"0.1.0",
			packs.SupportedManifestFormatVersion,
			`{"min":"0.2.0","maxExclusive":"0.3.0"}`,
			"nexus-pack-sha256-v1:0000000000000000000000000000000000000000000000000000000000000000",
			"nexus-pack-sha256-v1:0000000000000000000000000000000000000000000000000000000000000000",
			packs.PackPayloadHashAlgorithmV1,
			packs.PackSourceKindLocalPath,
			root,
			nil,
			nil,
		))
	expectNoPackOwnedApprovalProcesses(mock, "jira-like-sample")
	err = verifyInstalledAppPacks(context.Background(), database.NewConnectionFromDB(db), nil, false)
	if err == nil {
		t.Fatal("verifyInstalledAppPacks = nil, want invalid frozen formula error")
	}
	for _, want := range []string{
		"resolve installed source-backed pack jira-like-sample",
		"field.formula.expression_on_non_formula_type",
		`Issue.FrozenEcho`,
	} {
		if !strings.Contains(err.Error(), want) {
			t.Fatalf("verifyInstalledAppPacks error = %v, want %q in fail-closed resolver diagnostic", err, want)
		}
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("sql expectations: %v", err)
	}
}
