package tests

import (
	"encoding/json"
	"net/http"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/billing2/api"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/model/billing"
	"github.com/pingcap/dbaas/billing2/utils/ginutils"
	"github.com/pingcap/dbaas/billing2/utils/panicIf"
	"github.com/pingcap/dbaas/billing2/utils/tests"
	"github.com/pingcap/dbaas/billing2/utils/tests/datainit"
	"github.com/shopspring/decimal"
	"github.com/stretchr/testify/suite"
)

type MeasureTestSuite struct {
	tests.BillingTestSuite
	router *gin.Engine
}

func (suite *MeasureTestSuite) SetupTest() {
	suite.BillingTestSuite.SetupTest()
	datainit.CreatePaymentMock(uint(1))
	suite.router = gin.New()
	suite.router.Use(ginutils.ErrorMiddleWare)
	api.InitializeMeasureRouter(ginutils.MyRoute{Route: suite.router})
	_, err := (&billing.UnitModel{}).CreateUnit(&forms.UnitInfo{
		UnitKey: "test-unit",
	})
	panicIf.Error(err)
}

func TestMeasureSuite(t *testing.T) {
	suite.Run(t, new(MeasureTestSuite))
}

func (suite *MeasureTestSuite) TestMeasureCost() {
	assert := suite.Assert()
	tenantID := uint(1)

	packageInfo := &forms.PackageInfo{
		UnitPrices: forms.UnitPrices{
			"test-unit": {Price: decimal.NewFromInt(1)},
		},
		Discount:      decimal.NewFromInt(1),
		Credits:       decimal.NewFromInt(100),
		CreditsEnable: true,
	}
	info, _ := (&billing.PackageModel{}).CreatePackage(packageInfo)
	(&billing.BindedPackageModel{}).BindPackage(tenantID, info.PackageID)
	unitCosts := forms.UnitCosts{
		Unit: "test-unit",
		Cost: 1,
	}
	w := tests.PerformRequest(suite.router, "POST", "/tenants/1/measures", unitCosts)
	assert.Equal(http.StatusOK, w.Code)
}

func (suite *MeasureTestSuite) TestMeasureCostDryrun() {
	assert := suite.Assert()
	tenantID := uint(1)

	packageInfo := &forms.PackageInfo{
		UnitPrices: forms.UnitPrices{
			"test-unit": {Price: decimal.NewFromInt(1)},
		},
		Discount:      decimal.NewFromInt(1),
		Credits:       decimal.NewFromInt(100),
		CreditsEnable: true,
	}
	info, _ := (&billing.PackageModel{}).CreatePackage(packageInfo)
	bindedInfo, _ := (&billing.BindedPackageModel{}).BindPackage(tenantID, info.PackageID)
	unitCosts := forms.UnitCosts{
		Unit: "test-unit",
		Cost: 1,
	}
	w := tests.PerformRequest(suite.router, "POST", "/tenants/1/measures/dryrun", unitCosts)
	assert.Equal(http.StatusOK, w.Code)
	res := forms.UnitCosts{}
	assert.NoError(json.Unmarshal(w.Body.Bytes(), &res))
	assert.Equal(res.CostPrice, decimal.NewFromInt(1))
	bindedInfo, err := (&billing.BindedPackageModel{}).GetBindedPackage(bindedInfo.BindedPackageID)
	assert.NoError(err)
	assert.Equal(bindedInfo.RemainingCredits, decimal.NewFromInt(100))
}
