///|
pub enum BalanceStatus {
  Balanced
  Unbalanced
  Invalid
} derive(Debug, Eq)

///|
pub struct Tolerance {
  scaled : Int
} derive(Debug, Eq)

///|
pub struct BalanceCheck {
  status : BalanceStatus
  inlet : String
  outlet : String
  difference : String
  tolerance : String
} derive(Debug, Eq)

///|
pub fn tolerance(value : String) -> Tolerance {
  { scaled: decimal_scaled(value).unwrap_or(0).abs() }
}

///|
pub fn check_balance(
  inlet : String,
  outlet : String,
  tolerance : Tolerance,
) -> BalanceCheck {
  let left = decimal_scaled(inlet)
  let right = decimal_scaled(outlet)
  if left is None || right is None {
    return {
      status: Invalid,
      inlet,
      outlet,
      difference: "invalid",
      tolerance: "invalid",
    }
  }
  let difference = (left.unwrap() - right.unwrap()).abs()
  {
    status: if difference <= tolerance.scaled {
      Balanced
    } else {
      Unbalanced
    },
    inlet,
    outlet,
    difference: scaled_string(difference),
    tolerance: scaled_string(tolerance.scaled),
  }
}

///|
pub fn BalanceCheck::is_balanced(self : BalanceCheck) -> Bool {
  self.status == Balanced
}