package adapterimpl

import (
	"context"
	"strconv"

	br "github.com/tidbcloud/serverless-service/idl/pbgen/proto/rpc"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/adapter"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/infra/adapterimpl/cli"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

type brServiceImpl struct{}

func NewBRService() adapter.BRService {
	return &brServiceImpl{}
}

func (s *brServiceImpl) SetBackupPolicy(
	ctx context.Context,
	clusterId string,
	tenantId, projectId uint64,
	policy *globalserverlessv1.AutomatedBackupPolicy,
) bizerr.BizError {
	if policy == nil {
		return bizerr.New(bizerr.ErrCodeParams, "invalid argument")
	}

	return cli.UpdateBackupSchedule(ctx, &br.UpdateBackupPolicyRequest{
		ClusterId:    clusterId,
		OrgId:        tenantId,
		ProjectId:    projectId,
		ScheduleTime: policy.GetBackupTime(),
		Retention:    policy.GetRetentionDays(),
	})
}

func (s *brServiceImpl) GetAutoBackupPolicy(
	ctx context.Context,
	clusterId string,
	tenantId, projectId uint64,
) (*globalserverlessv1.AutomatedBackupPolicy, bizerr.BizError) {
	backupPolicys, err := cli.ListAutoBackupSetting(ctx, &br.ListBackupPoliciesRequest{
		ClusterId: clusterId,
		OrgId:     tenantId,
		ProjectId: projectId,
	})

	if err != nil {
		return nil, err
	}

	// not get backup policy from br service
	if len(backupPolicys) == 0 || backupPolicys[0] == nil {
		tilog.Warn(ctx, "empty backup policy", zap.String("cluster", clusterId))
		return &globalserverlessv1.AutomatedBackupPolicy{}, nil
	}

	return &globalserverlessv1.AutomatedBackupPolicy{
		BackupTime:    backupPolicys[0].GetScheduleTime(),
		RetentionDays: backupPolicys[0].GetRetention(),
	}, nil
}

type fakeDataflowServiceImpl struct{}

func NewFakeDataflowServiceImpl() adapter.BRService {
	return &fakeDataflowServiceImpl{}
}

func (s *fakeDataflowServiceImpl) SetBackupPolicy(
	ctx context.Context,
	clusterId string,
	tenantId, projectId uint64,
	policy *globalserverlessv1.AutomatedBackupPolicy,
) bizerr.BizError {
	if clusterId == "" || tenantId == 0 || projectId == 0 || policy == nil {
		return bizerr.New(bizerr.ErrCodeParams, "invalid argument")
	}

	if _, err := strconv.ParseUint(clusterId, 10, 64); err != nil {
		return bizerr.New(bizerr.ErrCodeParams, "invalid cluster id")
	}

	return nil
}

func (s *fakeDataflowServiceImpl) GetAutoBackupPolicy(
	ctx context.Context,
	clusterId string,
	tenantId, projectId uint64,
) (*globalserverlessv1.AutomatedBackupPolicy, bizerr.BizError) {
	if clusterId == "" || tenantId == 0 || projectId == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "invalid argument")
	}

	if _, err := strconv.ParseUint(clusterId, 10, 64); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "invalid cluster id")
	}

	return &globalserverlessv1.AutomatedBackupPolicy{}, nil
}
