///|
fn relation_for(route : RouteAnnouncement, vrp : Vrp) -> VrpRelation {
  let asn_matches = route.origin_asn() == vrp.asn()
  let length_allowed = route.prefix().length() <= vrp.max_length()
  match (asn_matches, length_allowed) {
    (true, true) => Authorizes
    (false, true) => AsnMismatch
    (true, false) => LengthExceeded
    (false, false) => AsnAndLengthMismatch
  }
}

///|
/// Validate a route against a complete set of validated ROA payloads.
///
/// Every covering VRP is retained as evidence. A route is valid if at least
/// one covering VRP authorizes both its origin ASN and prefix length.
pub fn validate_route(
  route : RouteAnnouncement,
  vrps : Array[Vrp],
) -> ValidationDecision {
  let matches : Array[VrpMatch] = []
  let mut authorized = false
  for vrp in vrps {
    if vrp.prefix().covers(route.prefix()) {
      let relation = relation_for(route, vrp)
      if relation == Authorizes {
        authorized = true
      }
      matches.push({ vrp, relation, })
    }
  }
  let validity = if authorized {
    Valid
  } else if matches.is_empty() {
    NotFound
  } else {
    Invalid
  }
  { route, validity, matches, }
}

///|
/// Validate routes in input order against the same VRP set.
pub fn validate_routes(
  routes : Array[RouteAnnouncement],
  vrps : Array[Vrp],
) -> Array[ValidationDecision] {
  let decisions : Array[ValidationDecision] = []
  for route in routes {
    decisions.push(validate_route(route, vrps))
  }
  decisions
}