package action

import (
	"fmt"
	"strings"

	clusterngv1beta "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/workflow/metric"
)

const regionalFailureUnspecifiedCode = "REGIONAL_FAILURE_UNSPECIFIED"

func recordRegionalRestoreFailure(clusterID, mode, action string, failure *clusterngv1beta.RestoreFailure) {
	source, code := regionalRestoreFailureLabels(failure)
	metric.RecordRestoreTerminalFailure(clusterID, mode, action, source, code)
}

func regionalRestoreFailureError(
	action string,
	failure *clusterngv1beta.RestoreFailure,
	fallbackMessage string,
) error {
	code := regionalFailureUnspecifiedCode
	message := fallbackMessage
	if failure != nil {
		if failure.GetCode() != "" {
			code = failure.GetCode()
		}
		if failure.GetMessage() != "" {
			message = failure.GetMessage()
		}
	}
	if message == "" {
		message = "no failure details provided"
	}
	return fmt.Errorf(
		"%s failed in regional control plane, code: %s, message: %s",
		action,
		code,
		message,
	)
}

func regionalRestoreFailureLabels(failure *clusterngv1beta.RestoreFailure) (source, code string) {
	source = "control_plane"
	code = strings.ToLower(regionalFailureUnspecifiedCode)
	if failure != nil {
		switch failure.Source {
		case clusterngv1beta.RestoreFailureSource_KERNEL:
			source = "kernel"
		case clusterngv1beta.RestoreFailureSource_CONTROL_PLANE:
			source = "control_plane"
		default:
			source = "unspecified"
		}
		switch strings.ToLower(failure.Code) {
		case "kernel_task_failed",
			"kernel_restore_conflict",
			"kernel_task_state_unknown",
			"classic_restore_failed",
			"packed_path_missing",
			"regional_failure_unspecified":
			code = strings.ToLower(failure.Code)
		}
	}
	return source, code
}
