package publicerror

import "sync/atomic"

type MetricCount struct {
	Code  string
	Count uint64
}

var observed = struct {
	upstreamConnectionInterrupted atomic.Uint64
	upstreamTimeout               atomic.Uint64
	upstreamRateLimited           atomic.Uint64
	upstreamUnavailable           atomic.Uint64
	upstreamInvalidResponse       atomic.Uint64
	upstreamAuthFailed            atomic.Uint64
	upstreamRequestRejected       atomic.Uint64
	gatewayRateLimited            atomic.Uint64
	storageWriteFailed            atomic.Uint64
	storageReadFailed             atomic.Uint64
	resultExpired                 atomic.Uint64
	resultUnavailable             atomic.Uint64
	invalidParameter              atomic.Uint64
	gatewayError                  atomic.Uint64
}{}

func Observe(value Error) {
	switch value.Code {
	case "upstream_connection_interrupted":
		observed.upstreamConnectionInterrupted.Add(1)
	case "upstream_timeout":
		observed.upstreamTimeout.Add(1)
	case "upstream_rate_limited":
		observed.upstreamRateLimited.Add(1)
	case "upstream_unavailable":
		observed.upstreamUnavailable.Add(1)
	case "upstream_invalid_response":
		observed.upstreamInvalidResponse.Add(1)
	case "upstream_auth_failed":
		observed.upstreamAuthFailed.Add(1)
	case "upstream_request_rejected":
		observed.upstreamRequestRejected.Add(1)
	case "upstream_invalid_request", "upstream_not_found", "upstream_method_not_allowed", "upstream_conflict", "upstream_payload_too_large", "upstream_unsupported_media_type", "upstream_unprocessable_request":
		observed.upstreamRequestRejected.Add(1)
	case "gateway_rate_limited":
		observed.gatewayRateLimited.Add(1)
	case "storage_write_failed":
		observed.storageWriteFailed.Add(1)
	case "storage_read_failed":
		observed.storageReadFailed.Add(1)
	case "result_expired":
		observed.resultExpired.Add(1)
	case "result_unavailable":
		observed.resultUnavailable.Add(1)
	case "invalid_parameter":
		observed.invalidParameter.Add(1)
	default:
		observed.gatewayError.Add(1)
	}
}

func MetricSnapshot() []MetricCount {
	return []MetricCount{
		{Code: "upstream_connection_interrupted", Count: observed.upstreamConnectionInterrupted.Load()},
		{Code: "upstream_timeout", Count: observed.upstreamTimeout.Load()},
		{Code: "upstream_rate_limited", Count: observed.upstreamRateLimited.Load()},
		{Code: "upstream_unavailable", Count: observed.upstreamUnavailable.Load()},
		{Code: "upstream_invalid_response", Count: observed.upstreamInvalidResponse.Load()},
		{Code: "upstream_auth_failed", Count: observed.upstreamAuthFailed.Load()},
		{Code: "upstream_request_rejected", Count: observed.upstreamRequestRejected.Load()},
		{Code: "gateway_rate_limited", Count: observed.gatewayRateLimited.Load()},
		{Code: "storage_write_failed", Count: observed.storageWriteFailed.Load()},
		{Code: "storage_read_failed", Count: observed.storageReadFailed.Load()},
		{Code: "result_expired", Count: observed.resultExpired.Load()},
		{Code: "result_unavailable", Count: observed.resultUnavailable.Load()},
		{Code: "invalid_parameter", Count: observed.invalidParameter.Load()},
		{Code: "gateway_error", Count: observed.gatewayError.Load()},
	}
}
