// This program has been developed by students from the bachelor Computer Science at Utrecht
// University within the Software Project course.
// © Copyright Utrecht University (Department of Information and Computing Sciences)
import type {PhaseNode} from "../pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx";

/**
 * takes an array of phaseNodes and orders them according to their nextPhaseId attributes,
 * starting with the phase that has isFirstPhase = true
 *
 * @param {PhaseNode[]} nodes an unordered phaseNode array
 * @returns {PhaseNode[]} the ordered phaseNode array
 */
export default function orderPhaseNodeArray(nodes: PhaseNode[]) : PhaseNode[] {
  // find the first phaseNode of the sequence
  const start = nodes.find(node => node.data.isFirstPhase);
  if (!start) {
    throw new Error('No phaseNode with isFirstObject = true found');
  }

  // prepare for ordering of phaseNodes
  const orderedPhaseNodes: PhaseNode[] = [];
  const IdMap = new Map(nodes.map(node => [node.id, node]));
  let currentNode: PhaseNode | undefined = start;

  // populate orderedPhaseNodes array with the phaseNodes in the correct order
  while (currentNode) {
    orderedPhaseNodes.push(currentNode);

    if (!currentNode.data.nextPhaseId) {
      throw new Error("Incomplete phase sequence, program does not reach the end node");
    }

    if (currentNode.data.nextPhaseId === "end") break;

    currentNode = IdMap.get(currentNode.data.nextPhaseId);

    if (!currentNode) {
      throw new Error(`Incomplete phase sequence, phaseNode with id "${orderedPhaseNodes.at(-1)?.data.nextPhaseId}" not found`);
    }
  }

  return orderedPhaseNodes;
}