import {
	TableType,
} from "qrc:/js/lib/generated/enum";
import {
	getTable,
} from "qrc:/js/lib/table_utils";
import {
	visitMaximalPaths,
} from "qrc:/js/lib/graph_utils";
import {
	computeNodeTimes,
	getFixedMultiplicity,
} from "./export_calc_times";
import {
	CalcCache,
} from "./export_calc_cache";

/**
 * Best case time to manufacture all components of the graph.
 *
 * The time consists of both manufacturing times and the idle periods.
 *
 * "Best case": This time can be reached if all possible processes are handled in parallel.
 *
 * The resulting time is defined by the most time-consuming maximal path through the graph.
 */
export function computeMinCompletionTime(calcCache?: CalcCache): number {
	const table = getTable(TableType.processIdlePeriod);
	let maxTimeInS = 0;
	visitMaximalPaths((path: Vertex[]) => {
		const idleTimeInS = path.reduce((acc, vertex) => {
			const processId = wsi4.node.processId(vertex);
			const entry = table.find(row => row.processId === processId);
			// [h] -> [s]
			return entry === undefined ? acc : acc + 3600 * entry.time;
		}, 0);
		const manufacturingTimeInS = path.reduce((acc, vertex) => {
			const times = computeNodeTimes(vertex, getFixedMultiplicity(vertex), calcCache);
			return acc + times.setup + times.unit;
		}, 0);
		maxTimeInS = Math.max(maxTimeInS, idleTimeInS + manufacturingTimeInS);
	});
	return maxTimeInS;
}
