// Non-geographic E.164 networks: +800, +808, +870, +878, +881, +882, +883, +888 and +979.
//
// These describe services rather than places, so they are keyed by calling
// code instead of by region. Extracted from the same upstream metadata as the
// region table (see data/numbering-plans.json for the source and its checksum).

///|
/// One non-geographic network: its calling code and the rules it publishes.
priv struct NonGeoPlan {
  calling_code : Int32
  general : String
  types : Array[PlanType]
}

///|
fn plan_non_geo(
  calling_code : Int32,
  general : String,
  types : Array[PlanType],
) -> NonGeoPlan {
  { calling_code, general, types, }
}

///|
/// The network that uses a calling code, or None.
fn find_non_geo(cc : Int32) -> NonGeoPlan? {
  for p in non_geo_plans {
    if p.calling_code == cc {
      return Some(p)
    }
  }
  None
}

///|
fn non_geo_possible(pn : PhoneNumber) -> Bool {
  if pn.national_number == "" ||
    digits_of(pn.national_number) != pn.national_number {
    return false
  }
  match find_non_geo(pn.country_code) {
    None => false
    Some(p) => {
      for t in p.types {
        if t.national.contains(pn.national_number.length()) {
          return true
        }
      }
      false
    }
  }
}

///|
/// True when the number is a valid number of its non-geographic network.
fn non_geo_admits(pn : PhoneNumber) -> Bool {
  match find_non_geo(pn.country_code) {
    None => false
    Some(p) =>
      if !matches_pattern(p.general, pn.national_number) {
        false
      } else {
        let mut hit = false
        for t in p.types {
          if type_rule_matches(t, pn.national_number) {
            hit = true
          }
        }
        hit
      }
  }
}

///|
/// The type the network's rules report, in libphonenumber's precedence.
fn non_geo_type(pn : PhoneNumber) -> NumberType? {
  match find_non_geo(pn.country_code) {
    None => None
    Some(p) => {
      if !matches_pattern(p.general, pn.national_number) {
        return None
      }
      for t in p.types {
        if type_rule_matches(t, pn.national_number) {
          return Some(t.kind)
        }
      }
      None
    }
  }
}