# Copyright (C) 2024 Manuel Bustillo

class AffinityGroupsHierarchy < Array
  include Singleton

  def initialize
    super
    @references = {}

    Group.roots.each do |group|
      self << group.id

      hydrate(group)
    end
  end

  def find(id)
    @references[id]
  end

  def <<(id)
    new_node = Tree::TreeNode.new(id)
    super(new_node).tap { @references[id] = new_node }
  end

  def register_child(parent_id, child_id)
    @references[parent_id] << Tree::TreeNode.new(child_id).tap { |child_node| @references[child_id] = child_node }
  end

  def distance(id_a, id_b)
    return nil if @references[id_a].nil? || @references[id_b].nil?

    @references[id_a].distance_to_common_ancestor(@references[id_b])
  end

  private

  def hydrate(group)
    group.children.each do |child|
      register_child(group.id, child.id)

      hydrate(child)
    end
  end
end