package connector_oauth

import (
	"errors"
	"strings"
)

func safeProviderError(operation string, err error) error {
	if err == nil {
		return nil
	}
	kind := ProviderErrorTransient
	if safeOperation(operation) == "exchange" || safeOperation(operation) == "refresh" {
		kind = ProviderErrorUncertain
	}
	code := "provider_error"
	var providerErr *ProviderError
	if errors.As(err, &providerErr) && providerErr != nil {
		switch providerErr.Kind {
		case ProviderErrorAuthorization, ProviderErrorRejected, ProviderErrorTransient, ProviderErrorUncertain:
			kind = providerErr.Kind
		}
		code = safeProviderCode(providerErr.Code)
	}
	return &ProviderError{Operation: safeOperation(operation), Kind: kind, Code: code}
}

func safeOperation(operation string) string {
	switch strings.ToLower(strings.TrimSpace(operation)) {
	case "authorization", "exchange", "identity", "refresh", "revoke":
		return strings.ToLower(strings.TrimSpace(operation))
	default:
		return "operation"
	}
}

func safeProviderCode(code string) string {
	switch strings.ToLower(strings.TrimSpace(code)) {
	case "access_denied", "invalid_grant", "invalid_token", "unauthorized",
		"rate_limited", "provider_rejected", "temporarily_unavailable",
		"transport_error", "provider_error":
		return strings.ToLower(strings.TrimSpace(code))
	default:
		return "provider_error"
	}
}
