package org.openlca.io.maps;

import org.openlca.core.model.Copyable;

/**
 * Describes a single mapping between two flows.
 *
 * @param sourceFlow the source/original flow of the mapping
 * @param targetFlow the corresponding target flow of the mapping
 * @param factor     the conversion factor which is applied to the amounts of
 *                   the source flow to convert them into the corresponding
 *                   amounts of the target flow (in the respective flow
 *                   properties and units); defaults to 1.0
 */
public record FlowMapEntry(
	FlowRef sourceFlow,
	FlowRef targetFlow,
	double factor
) implements Copyable<FlowMapEntry> {

	public FlowMapEntry(FlowRef sourceFlow, FlowRef targetFlow) {
		this(sourceFlow, targetFlow, 1);
	}

	/**
	 * Swap the source and target flow reference in this entry and inverts the
	 * conversion factor.
	 */
	public FlowMapEntry swap() {
		var inv = factor == 0 || factor == 1
			? factor
			: 1 / factor;
		return new FlowMapEntry(targetFlow, sourceFlow, inv);
	}

	public String sourceFlowId() {
		if (sourceFlow == null || sourceFlow.flow == null)
			return null;
		return sourceFlow.flow.refId;
	}

	public String targetFlowId() {
		if (targetFlow == null || targetFlow.flow == null)
			return null;
		return targetFlow.flow.refId;
	}

	@Override
	public FlowMapEntry copy() {
		var sourceCopy = sourceFlow != null
			? sourceFlow.copy()
			: null;
		var targetCopy = targetFlow != null
			? targetFlow.copy()
			: null;
		return new FlowMapEntry(sourceCopy, targetCopy, factor);
	}
}

@@ -548,30 +548,73 @@
 lic 
-record FlowMapEntry(%0A%09
+class FlowMapEntry implements Copyable%3CFlowMapEntry%3E %7B%0A%0A%09private 
 Flow
@@ -627,19 +627,27 @@
 urceFlow
-,
+;
 %0A%09
+private 
 FlowRef 
@@ -660,11 +660,19 @@
 Flow
-,
+;
 %0A%09
+private 
 doub
@@ -684,46 +684,281 @@
 ctor
-%0A) implements Copyable%3CFlowMapEntry%3E %7B
+;%0A%0A%09public FlowMapEntry(FlowRef sourceFlow, FlowRef targetFlow) %7B%0A%09%09this(sourceFlow, targetFlow, 1);%0A%09%7D%0A%0A%09public FlowMapEntry(FlowRef sourceFlow, FlowRef targetFlow, double factor) %7B%0A%09%09this.sourceFlow = sourceFlow;%0A%09%09this.targetFlow = targetFlow;%0A%09%09this.factor = factor;%0A%09%7D
 %0A%0A%09p
@@ -967,32 +967,43 @@
 lic FlowMapEntry
+ sourceFlow
 (FlowRef sourceF
@@ -1009,65 +1009,409 @@
 Flow
-, FlowRef targetFlow) %7B%0A%09%09this(sourceFlow, targetFlow, 1)
+) %7B%0A%09%09this.sourceFlow = sourceFlow;%0A%09%09return this;%0A%09%7D%0A%0A%09public FlowRef sourceFlow() %7B%0A%09%09return sourceFlow;%0A%09%7D%0A%0A%09public FlowMapEntry targetFlow(FlowRef targetFlow) %7B%0A%09%09this.targetFlow = targetFlow;%0A%09%09return this;%0A%09%7D%0A%0A%09public FlowRef targetFlow() %7B%0A%09%09return targetFlow;%0A%09%7D%0A%0A%09public FlowMapEntry factor(double factor) %7B%0A%09%09this.factor = factor;%0A%09%09return this;%0A%09%7D%0A%0A%09public double factor() %7B%0A%09%09return factor
 ;%0A%09%7D
@@ -1529,28 +1529,20 @@
 %09public 
-FlowMapEntry
+void
  swap() 
@@ -1549,40 +1549,34 @@
 %7B%0A%09%09
-var inv = 
+if (
 factor 
-=
+!
 = 0 
-%7C%7C
+&&
  factor 
 == 1
@@ -1575,29 +1575,27 @@
 tor 
-=
+!
 = 1
+) %7B
 %0A%09%09%09
-? 
 factor
-%0A%09%09%09:
+ =
  1 /
@@ -1609,60 +1609,75 @@
 ;%0A%09%09
-return new FlowMapEntry(targetFlow, sourceFlow, inv)
+%7D%0A%09%09var s = sourceFlow;%0A%09%09sourceFlow = targetFlow;%0A%09%09targetFlow = s
 ;%0A%09%7D

make the FlowMapEntry mutable again