package sqsmeasurehandler

import (
	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"github.com/tidbcloud/tiinf/sdk/measure"
	"go.uber.org/zap"
)

type MeasureSender interface {
	SendMeasure(tenantID uint, cost *forms.UnitCosts) error
}

func NewSQSBillingMeasure(tenantID uint, cost *forms.UnitCosts) *measure.BillingMeasure {
	return &measure.BillingMeasure{
		TenantID:      uint64(tenantID),
		CostID:        cost.CostID,
		Cost:          int64(cost.Cost),
		CostTimestamp: cost.CostTimeStamp,
		Labels:        cost.Labels,
		Unit:          cost.Unit,
	}
}

var sender MeasureSender

func GetMeasureSender() MeasureSender {
	return sender
}

func SetMeasureSender(s MeasureSender) {
	sender = s
}

type SQSMeasureSender struct {
	handler *measure.MeasureSQSImpl
}

func (s *SQSMeasureSender) SendMeasure(tenantID uint, cost *forms.UnitCosts) error {
	input := NewSQSBillingMeasure(tenantID, cost)
	return s.handler.SendMeasure(*input)
}

func NewSQSMeasureSender() (*SQSMeasureSender, error) {
	h := &measure.MeasureSQSImpl{}
	err := h.InitMeasureSqsHandler(config.Get().GetString(config.ENV), "")
	if err != nil {
		log.Error("failed to init MeasureSqsHandler", zap.Error(err))
		return nil, err
	}
	return &SQSMeasureSender{
		handler: h,
	}, err
}

func SetDefaultMeasureSender() error {
	s, err := NewSQSMeasureSender()
	if err != nil {
		return err
	}
	SetMeasureSender(s)
	return nil
}

type MeasureSQSMock struct {
	Queue []measure.BillingMeasure
}

func (s *MeasureSQSMock) SendMeasure(tenantID uint, cost *forms.UnitCosts) error {
	billingMeasure := NewSQSBillingMeasure(tenantID, cost)
	s.Queue = append(s.Queue, *billingMeasure)
	return nil
}

func SetMockMeasureSender() {
	SetMeasureSender(&MeasureSQSMock{})
}
