package deploy

import (
	"errors"

	ctrl "sigs.k8s.io/controller-runtime"
)

// ErrorRequeueOnly is a special error to indicate only requeue for re-sync and do not touch the phase.
var ErrorRequeueOnly = errors.New("requeue only")

type retriableError struct {
	err    error
	result ctrl.Result
}

func NewRetriableError(err error, result ctrl.Result) error {
	if result.IsZero() {
		panic("zero value result")
	}

	if err != nil {
		if e, ok := err.(*retriableError); ok {
			e.result = result
			return e
		}
	}

	return &retriableError{
		err:    err,
		result: result,
	}
}

func (e *retriableError) Error() string {
	if e == nil || e.err == nil {
		return ""
	}
	return e.err.Error()
}

// ShouldRequeue extracts the requeue result from the retriable error.
func ShouldRequeue(err error) ctrl.Result {
	if e, ok := err.(*retriableError); ok {
		return e.result
	}

	return ctrl.Result{}
}

// RequeueOnly indicates only requeue for re-sync, and no need to touch the current phase.
func RequeueOnly(err error) bool {
	if e, ok := err.(*retriableError); ok {
		return e.err == ErrorRequeueOnly
	}
	return false
}
