package tests

import (
	"testing"

	"github.com/pingcap/dbaas/billing2/billing_errors"
	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/model/creditriskcontrol"
	"github.com/pingcap/dbaas/billing2/utils/tests"
	"github.com/shopspring/decimal"
	"github.com/stretchr/testify/suite"
)

type CreditRiskLevelTestSuite struct {
	tests.BillingTestSuite
}

func TestCreditRiskLevelSuite(t *testing.T) {
	suite.Run(t, new(CreditRiskLevelTestSuite))
}

var creditRiskLevelModel = &creditriskcontrol.CreditRiskLevelModel{}

func (s *CreditRiskLevelTestSuite) TestCRUDCreditRiskLevel() {
	assert := s.Assert()
	creditCreditRiskLevel := &forms.CreditRiskLevel{
		Name: "test",
	}
	info, err := creditRiskLevelModel.CreateCreditRiskLevel(creditCreditRiskLevel)
	assert.NoError(err)
	assert.Equal(info.Name, "test")

	info, err = creditRiskLevelModel.GetCreditRiskLevel(info.CreditRiskLevelID)
	assert.NoError(err)
	assert.Equal(info.Name, "test")
	assert.Equal(info.CostQuota.CostQuotaLimit, decimal.NewFromInt(config.Get().GetInt64(config.DefaultCostQuota)))

	creditCreditRiskLevel.Name = "test1"
	err = creditRiskLevelModel.UpdateCreditRiskLevel(info.CreditRiskLevelID, creditCreditRiskLevel)
	assert.NoError(err)

	info, err = creditRiskLevelModel.GetCreditRiskLevel(info.CreditRiskLevelID)
	assert.NoError(err)
	assert.Equal(info.Name, "test1")

	allInfos, err := creditRiskLevelModel.ListAllCreditRiskLevels()
	assert.NoError(err)
	assert.Len(allInfos, 1)

	config.Get().Set(config.DefaultCreditRiskLevel, info.CreditRiskLevelID)

	err = creditRiskLevelModel.DeleteCreditRiskLevel(info.CreditRiskLevelID)
	assert.Error(err, billing_errors.InvalidInputError)

	config.Get().Set(config.DefaultCreditRiskLevel, 0)

	err = creditRiskLevelModel.DeleteCreditRiskLevel(info.CreditRiskLevelID)
	assert.NoError(err)

	_, err = creditRiskLevelModel.GetCreditRiskLevel(info.CreditRiskLevelID)
	assert.ErrorIs(err, billing_errors.ObjectNotExistsError)

}

func (s *CreditRiskLevelTestSuite) TestTenantCreditRiskLevel() {
	assert := s.Assert()

	creditCreditRiskLevel := &forms.CreditRiskLevel{
		Name: "test_default",
	}
	info, err := creditRiskLevelModel.CreateCreditRiskLevel(creditCreditRiskLevel)
	assert.NoError(err)
	assert.Equal(info.Name, "test_default")

	config.Get().Set(config.DefaultCreditRiskLevel, info.CreditRiskLevelID)

	tenantID := uint(1)
	creditCreditRiskLevelID, err := creditRiskLevelModel.GetTenantCreditRiskLevelID(tenantID)
	assert.NoError(err)
	assert.Equal(creditCreditRiskLevelID, info.CreditRiskLevelID)

	creditCreditRiskLevel = &forms.CreditRiskLevel{
		Name: "test",
	}
	info1, err := creditRiskLevelModel.CreateCreditRiskLevel(creditCreditRiskLevel)
	assert.NoError(err)
	assert.Equal(info.Name, "test_default")

	err = creditRiskLevelModel.SetTenantCreditRiskLevel(tenantID, info1.CreditRiskLevelID)
	assert.NoError(err)
}
