// Relative Strength Index (J. Welles Wilder, 1978).

///|
/// Number of leading NaN values produced by `rsi` for the given period.
pub fn rsi_lookback(period : Int32) -> Int32 {
  period
}

///|
/// Maps Wilder-smoothed average gain/loss to the RSI value. A zero average
/// loss maps to 100 (and a flat window therefore reads 100), matching
/// pandas-ta.
fn rsi_from(gain : Double, loss : Double) -> Double {
  if @base.is_nan(gain) || @base.is_nan(loss) {
    @base.nan()
  } else if loss == 0.0 {
    100.0
  } else {
    100.0 - 100.0 / (1.0 + gain / loss)
  }
}

///|
/// Relative Strength Index.
///
/// The seed is the simple average of gains and losses over the first
/// `period` price changes; later averages use Wilder smoothing
/// `avg = (prev * (period - 1) + current) / period`. The first value lands
/// at index `period`. NaN inputs poison the seed and propagate forward.
pub fn rsi(
  data : Array[Double],
  period : Int32,
) -> Array[Double] raise @base.TaError {
  @base.validate_series(data, period)
  let n = data.length()
  if period > n {
    raise @base.NotEnoughData("period \{period} exceeds input length \{n}")
  }
  let out : Array[Double] = []
  if period >= n {
    for _ in 0.. period {
    let mut g = 0.0
    let mut l = 0.0
    let mut ok = true
    for i in 1..<(period + 1) {
      let d = data[i] - data[i - 1]
      if @base.is_nan(d) {
        ok = false
        break
      }
      if d > 0.0 {
        g += d
      } else {
        l -= d
      }
    }
    if ok {
      avg_gain = g / period.to_double()
      avg_loss = l / period.to_double()
      seeded = true
    }
  }
  if seeded {
    out.push(rsi_from(avg_gain, avg_loss))
    let pm = (period - 1).to_double()
    let pd = period.to_double()
    for i in (period + 1).. 0.0 {
        avg_gain = (avg_gain * pm + d) / pd
        avg_loss = avg_loss * pm / pd
      } else {
        avg_gain = avg_gain * pm / pd
        avg_loss = (avg_loss * pm - d) / pd
      }
      out.push(rsi_from(avg_gain, avg_loss))
    }
  } else {
    for _ in period..