///|
fn asset_index(assets : Array[AssetRef], key : String) -> Int? {
  let mut result : Int? = None
  for i, asset in assets {
    if result is None && asset_ref_key(asset) == key {
      result = Some(i)
    }
  }
  result
}

///|
fn validate_assets(assets : Array[AssetRef]) -> Unit raise ModelError {
  for i in 0.. id.value
      Component(id) => id.value
    }
    if value == "" {
      let field = match assets[i] {
        Service(_) => "service_id"
        Component(_) => "component_id"
      }
      raise ModelError::EmptyField(field)
    }
    for j in 0.. (Array[Array[Int]], Array[Int]) raise ModelError {
  validate_assets(assets)
  let adjacency : Array[Array[Int]] = []
  let indegree : Array[Int] = []
  for _ in 0.. index
      None => raise ModelError::MissingAsset(dependency_key)
    }
    let dependent_index = match asset_index(assets, dependent_key) {
      Some(index) => index
      None => raise ModelError::MissingAsset(dependent_key)
    }
    for existing in adjacency[dependency_index] {
      if existing == dependent_index {
        raise ModelError::DuplicateDependency(
          "\{dependency_key} -> \{dependent_key}",
        )
      }
    }
    adjacency[dependency_index].push(dependent_index)
    indegree[dependent_index] = indegree[dependent_index] + 1
  }
  (adjacency, indegree)
}

///|
fn detect_cycle(
  node : Int,
  assets : Array[AssetRef],
  adjacency : Array[Array[Int]],
  state : Array[Int],
) -> Unit raise ModelError {
  if state[node] == 1 {
    raise ModelError::DependencyCycle(asset_ref_key(assets[node]))
  }
  if state[node] == 2 {
    ()
  } else {
    state[node] = 1
    for dependent in adjacency[node] {
      detect_cycle(dependent, assets, adjacency, state)
    }
    state[node] = 2
  }
}

///|
fn ensure_acyclic(
  assets : Array[AssetRef],
  adjacency : Array[Array[Int]],
) -> Unit raise ModelError {
  let state : Array[Int] = []
  for _ in 0.. Array[AssetRef] raise ModelError {
  let (adjacency, indegree) = build_adjacency(assets, dependencies)
  ensure_acyclic(assets, adjacency)
  let ready : Array[Int] = []
  for i in 0.. Unit raise ModelError {
  let _ = dependency_order(assets, dependencies)
}