{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

{- |
Module      :  OpenTelemetry.Debug.MetricExport
Copyright   :  (c) Ian Duncan, 2026
License     :  BSD-3
Description :  Human-readable rendering of 'ResourceMetricsExport' batches for tests and debugging.
Stability   :  experimental

This is not a stable interchange format.
-}
module OpenTelemetry.Debug.MetricExport (
  renderResourceMetricsExportDebug,
) where

import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.Text.Lazy.Builder (Builder, fromText, toLazyText)
import Data.Text.Lazy.Builder.Int (decimal)
import qualified Data.Vector as V
import OpenTelemetry.Exporter.Metric (
  MetricExport (..),
  ResourceMetricsExport (..),
  ScopeMetricsExport (..),
 )


{- | Multi-line text summary (not Prometheus or OTLP format).

@since 0.0.1.0
-}
renderResourceMetricsExportDebug :: [ResourceMetricsExport] -> Text
renderResourceMetricsExportDebug :: [ResourceMetricsExport] -> Text
renderResourceMetricsExportDebug [ResourceMetricsExport]
rs =
  Text -> [Text] -> Text
T.intercalate Text
"\n---\n" ((ResourceMetricsExport -> Text)
-> [ResourceMetricsExport] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ResourceMetricsExport -> Text
renderResource [ResourceMetricsExport]
rs)


renderResource :: ResourceMetricsExport -> Text
renderResource :: ResourceMetricsExport -> Text
renderResource ResourceMetricsExport {Vector ScopeMetricsExport
MaterializedResources
resourceMetricsResource :: MaterializedResources
resourceMetricsScopes :: Vector ScopeMetricsExport
resourceMetricsResource :: ResourceMetricsExport -> MaterializedResources
resourceMetricsScopes :: ResourceMetricsExport -> Vector ScopeMetricsExport
..} =
  Text -> [Text] -> Text
T.intercalate Text
"\n" ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
    Text
"ResourceMetricsExport"
      Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (ScopeMetricsExport -> Text) -> [ScopeMetricsExport] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ScopeMetricsExport -> Text
renderScope (Vector ScopeMetricsExport -> [ScopeMetricsExport]
forall a. Vector a -> [a]
V.toList Vector ScopeMetricsExport
resourceMetricsScopes)


renderScope :: ScopeMetricsExport -> Text
renderScope :: ScopeMetricsExport -> Text
renderScope ScopeMetricsExport {Vector MetricExport
InstrumentationLibrary
scopeMetricsScope :: InstrumentationLibrary
scopeMetricsExports :: Vector MetricExport
scopeMetricsExports :: ScopeMetricsExport -> Vector MetricExport
scopeMetricsScope :: ScopeMetricsExport -> InstrumentationLibrary
..} =
  Text -> [Text] -> Text
T.intercalate Text
"\n" ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
    Text
"  ScopeMetricsExport"
      Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (MetricExport -> Text) -> [MetricExport] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\MetricExport
m -> Text -> Text -> Text
T.append Text
"    " (MetricExport -> Text
renderMetric MetricExport
m)) (Vector MetricExport -> [MetricExport]
forall a. Vector a -> [a]
V.toList Vector MetricExport
scopeMetricsExports)


renderMetric :: MetricExport -> Text
renderMetric :: MetricExport -> Text
renderMetric = LazyText -> Text
TL.toStrict (LazyText -> Text)
-> (MetricExport -> LazyText) -> MetricExport -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyText
toLazyText (Builder -> LazyText)
-> (MetricExport -> Builder) -> MetricExport -> LazyText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetricExport -> Builder
renderMetricB


renderMetricB :: MetricExport -> Builder
renderMetricB :: MetricExport -> Builder
renderMetricB = \case
  MetricExportSum Text
n Text
d Text
u InstrumentationLibrary
_ Bool
m Bool
i AggregationTemporality
_ Vector SumDataPoint
pts ->
    Builder
"Sum "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
n
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
d
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
u
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" monotonic="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
showBool Bool
m
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" isInt="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
showBool Bool
i
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" nPts="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal (Vector SumDataPoint -> Int
forall a. Vector a -> Int
V.length Vector SumDataPoint
pts)
  MetricExportHistogram Text
n Text
d Text
u InstrumentationLibrary
_ AggregationTemporality
_ Vector HistogramDataPoint
pts ->
    Builder
"Histogram "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
n
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
d
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
u
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" nPts="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal (Vector HistogramDataPoint -> Int
forall a. Vector a -> Int
V.length Vector HistogramDataPoint
pts)
  MetricExportExponentialHistogram Text
n Text
d Text
u InstrumentationLibrary
_ AggregationTemporality
_ Vector ExponentialHistogramDataPoint
pts ->
    Builder
"ExponentialHistogram "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
n
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
d
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
u
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" nPts="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal (Vector ExponentialHistogramDataPoint -> Int
forall a. Vector a -> Int
V.length Vector ExponentialHistogramDataPoint
pts)
  MetricExportGauge Text
n Text
d Text
u InstrumentationLibrary
_ Bool
i Vector GaugeDataPoint
pts ->
    Builder
"Gauge "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
n
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
d
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" "
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
fromText Text
u
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" isInt="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Bool -> Builder
showBool Bool
i
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" nPts="
      Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal (Vector GaugeDataPoint -> Int
forall a. Vector a -> Int
V.length Vector GaugeDataPoint
pts)


showBool :: Bool -> Builder
showBool :: Bool -> Builder
showBool Bool
True = Builder
"True"
showBool Bool
False = Builder
"False"