package server

import (
	"context"
	"fmt"

	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"github.com/tidbcloud/cluster-service-ng/domain/entity"
	"github.com/tidbcloud/cluster-service-ng/pkg/storage/mysql/schema"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type GetManualBackupInput struct {
	*apiv1.GetManualBackupRequest
}

type GetManualBackupOutput struct {
	*apiv1.ManualBackup
}

func (s *serverImpl) GetManualBackup(ctx context.Context, input *GetManualBackupInput) (*GetManualBackupOutput, error) {
	backup, err := s.manualBackupRepo.Load(ctx, input.ClusterId, input.BackupId, true)
	if err != nil {
		if status.Code(err) == codes.NotFound {
			return nil, status.Errorf(codes.NotFound, "ManualBackup not found")
		}
		tilog.Error(ctx, "failed to load manual backup record", zap.Error(err), zap.String("clusterId", input.ClusterId), zap.String("backupId", input.BackupId))
		return nil, fmt.Errorf("failed to load manual backup record: %w", err)
	}

	if backup.DeletedAt.Valid {
		return &GetManualBackupOutput{ManualBackup: &apiv1.ManualBackup{Status: apiv1.ManualBackup_DELETED}}, nil
	}

	resp := buildManualBackupOutput(backup)
	return &GetManualBackupOutput{ManualBackup: resp}, nil
}

func buildManualBackupOutput(backup *entity.ManualBackup) *apiv1.ManualBackup {
	out := &apiv1.ManualBackup{
		BackupTs: backup.BackupTs,
		// use the cluster size as backup size instead of actual backup file size
		BackupSize: backup.RestoreSize,
	}
	switch backup.Status {
	case schema.ManualBackupStatusRunning:
		out.Status = apiv1.ManualBackup_RUNNING
	case schema.ManualBackupStatusSucceeded:
		out.Status = apiv1.ManualBackup_SUCCEED
	case schema.ManualBackupStatusFailed:
		out.Status = apiv1.ManualBackup_FAILED
	case schema.ManualBackupStatusDeleting, schema.ManualBackupStatusDeleted:
		out.Status = apiv1.ManualBackup_DELETED
	}
	return out
}
