///|
/// Mutable scalar cell for deterministic single-threaded targets and tests.
///
/// Native builds use `native.mbt` instead. Keeping the portable backend
/// target-local avoids making the C pthread dependency part of Wasm/JS output.
#cfg(not(target="native"))
pub struct ScalarCell {
  mut value : Double
}

///|
#cfg(not(target="native"))
pub fn ScalarCell::new(initial : Double) -> ScalarCell {
  { value: initial }
}

///|
#cfg(not(target="native"))
pub fn ScalarCell::get(self : ScalarCell) -> Double {
  self.value
}

///|
#cfg(not(target="native"))
pub fn ScalarCell::set(self : ScalarCell, value : Double) -> Unit {
  self.value = value
}

///|
#cfg(not(target="native"))
pub fn ScalarCell::add(self : ScalarCell, delta : Double) -> Unit {
  self.value += delta
}

///|
/// No-op synchronization boundary for single-owner Wasm/Wasm-GC/JS targets.
/// Its API mirrors the native pthread mutex so callers keep one lock protocol
/// while target-specific code determines whether a lock is required.
#cfg(not(target="native"))
pub struct Mutex {
  state : Unit
}

///|
#cfg(not(target="native"))
pub fn Mutex::new() -> Mutex {
  { state: () }
}

///|
#cfg(not(target="native"))
pub fn Mutex::lock(self : Mutex) -> Unit {
  let _ = self.state
}

///|
#cfg(not(target="native"))
pub fn Mutex::unlock(self : Mutex) -> Unit {
  let _ = self.state
}

///|
/// Deterministic, single-threaded storage for one histogram.
///
/// The metric package validates bucket boundaries and observations before they
/// reach this cell. This deliberately does not claim cross-thread safety.
#cfg(not(target="native"))
pub struct HistogramCell {
  boundaries : Array[Double]
  bucket_counts : Array[Int64]
  mut count : Int64
  mut sum : Double
}

///|
#cfg(not(target="native"))
pub fn HistogramCell::new(boundaries : Array[Double]) -> HistogramCell {
  {
    boundaries: boundaries.copy(),
    bucket_counts: Array::make(boundaries.length(), 0L),
    count: 0L,
    sum: 0.0,
  }
}

///|
#cfg(not(target="native"))
pub fn HistogramCell::observe(self : HistogramCell, value : Double) -> Unit {
  self.count += 1L
  self.sum += value
  for index, boundary in self.boundaries {
    if value <= boundary {
      self.bucket_counts[index] += 1L
    }
  }
}

///|
#cfg(not(target="native"))
pub fn HistogramCell::snapshot(self : HistogramCell) -> HistogramCellSnapshot {
  {
    cumulative_counts: self.bucket_counts.copy(),
    count: self.count,
    sum: self.sum,
  }
}