package metering

import (
	"testing"
	"time"

	. "github.com/onsi/gomega"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/pkg/config"
)

func Test_skipSync2billing(t *testing.T) {
	g := NewWithT(t)
	nowSec := time.Now().Unix()
	svc := ReportMetering2billingSvc{
		cfg: &config.BillingConfig{
			InstanceMeteringSwitchTime: 0,
		},
	}

	ok := svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec,
	})
	// when the switch time is 0, the function should not skip any record
	g.Expect(ok).Should(BeFalse())

	svc.cfg.InstanceMeteringSwitchTime = uint64(nowSec)
	svc.cfg.InstanceMeteringSwitchTimeBlockList = []config.MeteringTenantFilter{
		{
			TenantID:   5,
			SwitchTime: uint64(nowSec + 100),
		},
	}
	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec,
	})
	// when the switch time is equal to the record's cost time, the function should skip the record
	g.Expect(ok).Should(BeTrue())
	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec - 1,
	})
	// when the switch time is big to the record's cost time, the function should not skip the record
	g.Expect(ok).Should(BeFalse())
	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec + 1,
	})
	// when the switch time is small to the record's cost time, the function should skip the record
	// and the tenant id is not in the block list
	g.Expect(ok).Should(BeTrue())
	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
		TenantID:          5,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec + 1,
	})
	// when the switch time is called and the tenant is in the block list, the function should not skip the record
	g.Expect(ok).Should(BeFalse())
	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
		TenantID:          5,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec + 200,
	})
	// when the switch time is called and the tenant is in the block list, the function should skip the record
	g.Expect(ok).Should(BeTrue())
	svc.cfg.InstanceMeteringSwitchTime = uint64(nowSec + 3000)
	svc.cfg.InstanceTenantSwitchFilter = []config.MeteringTenantFilter{
		{
			TenantID:   1,
			SwitchTime: uint64(nowSec),
		},
	}

	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
		TenantID:          1,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec,
	})
	// when the tenant  switch time is equal to the record's cost time and tenant is matched, the function should skip the record
	g.Expect(ok).Should(BeTrue())

	ok = svc.skipSync2billing(&entity.BillingReportRecord{
		ClusterMeteringID: 1,
		TenantID:          2,
	}, &entity.BillingMeteringReport{
		CostTimeStamp: nowSec,
	})
	// when the tenant  switch time is equal to the record's cost time and tenant is not matched, the function should not skip the record
	g.Expect(ok).Should(BeFalse())
}
