package bootstrapimpl

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/nexuscrm/shared/pkg/constants"
)

var sharingRuleQueryStr = regexp.QuoteMeta(fmt.Sprintf(
	"SELECT `%s`, `%s` FROM `%s` "+
		"WHERE COALESCE(`%s`,0) = 0 "+
		"AND COALESCE(NULLIF(TRIM(`%s`),''),'') != ''",
	constants.FieldObjectAPIName,
	constants.FieldSharingRule_Criteria,
	constants.TableSharingRule,
	constants.FieldIsDeleted,
	constants.FieldSharingRule_Criteria,
))

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

	objRows := sqlmock.NewRows([]string{
		constants.ColSysObject_ID,
		constants.ColSysObject_APIName,
		constants.FieldSysObject_ReadSource,
	}).AddRow("obj1", "Lead", nil)
	mock.ExpectQuery(objectQueryStr).WillReturnRows(objRows)

	fieldRows := sqlmock.NewRows([]string{
		constants.ColSysField_ObjectID,
		constants.ColSysField_APIName,
		"col",
	}).
		AddRow("obj1", "Region__c", "Region__c").
		AddRow("obj1", "Status__c", "Status__c").
		AddRow("obj1", "OwnerId", "OwnerId")
	mock.ExpectQuery(regexp.QuoteMeta(fmt.Sprintf(
		"SELECT `%s`, `%s`, COALESCE(NULLIF(`%s`,''), `%s`) FROM `%s` "+
			"WHERE COALESCE(`%s`,'') != 'active' "+
			"AND COALESCE(`%s`,0) = 0 "+
			"AND COALESCE(`%s`,0) = 0",
		constants.ColSysField_ObjectID,
		constants.ColSysField_APIName,
		constants.ColSysField_PhysicalName, constants.ColSysField_APIName,
		constants.TableField,
		constants.ColSysField_FormulaMode,
		constants.ColSysField_IsDeleted,
		constants.ColSysField_IsSystem,
	))).WillReturnRows(fieldRows)

	ruleRows := sqlmock.NewRows([]string{
		constants.FieldObjectAPIName,
		constants.FieldSharingRule_Criteria,
	}).AddRow("Lead", `Region__c == "APAC" || TEXT(Status__c) == "Open" || $User.Name == "Kevin" || Parent__r.Name == "Acme"`)
	mock.ExpectQuery(sharingRuleQueryStr).WillReturnRows(ruleRows)

	got, err := collectSharingRuleCriteriaColumns(db)
	if err != nil {
		t.Fatalf("collectSharingRuleCriteriaColumns() error = %v; want nil", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("unmet sqlmock expectations: %v", err)
	}

	cols := got["Lead"]
	if !cols["Region__c"] {
		t.Fatalf("collectSharingRuleCriteriaColumns()[Lead] missing Region__c: %v", cols)
	}
	if !cols["Status__c"] {
		t.Fatalf("collectSharingRuleCriteriaColumns()[Lead] missing Status__c: %v", cols)
	}
	if cols["Parent__r"] || cols["Name"] {
		t.Fatalf("collectSharingRuleCriteriaColumns()[Lead] should exclude relationship/global refs: %v", cols)
	}
}
