<commit_before>package cd4017be.indlog.multiblock;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.function.ToIntFunction;

import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraftforge.fluids.FluidStack;
import cd4017be.lib.TickRegistry;
import cd4017be.lib.TickRegistry.ITickReceiver;
import cd4017be.lib.templates.SharedNetwork;
import cd4017be.lib.tileentity.BaseTileEntity;
import cd4017be.lib.util.Utils;

/**
 * 
 * @author CD4017BE
 *
 */
public class WarpPipeNetwork extends SharedNetwork<WarpPipeNode, WarpPipeNetwork> implements ITickReceiver {

	public static byte TICKS;
	private static final byte SID = 1, SIS = 2, SFD = 4, SFS = 8;

	public HashSet<ITickable> activeCon = new HashSet<ITickable>();
	public ArrayList<IItemDest> itemDest = new ArrayList<IItemDest>();
	public ArrayList<IFluidDest> fluidDest = new ArrayList<IFluidDest>();
	public ArrayList<IItemSrc> itemSrc = new ArrayList<IItemSrc>();
	public ArrayList<IFluidSrc> fluidSrc = new ArrayList<IFluidSrc>();
	private byte sort = 0;
	public boolean disabled = true;
	public byte timer;

	public WarpPipeNetwork(WarpPipeNode core) {
		super(core);
		for (ConComp c : core.cons)
			if (c != null)
				addConnector(c);
	}

	protected WarpPipeNetwork(HashMap<Long, WarpPipeNode> comps) {
		super(comps);
		enable();
	}

	public void enable() {
		if (disabled) {
			disabled = false;
			TickRegistry.instance.add(this);
		}
	}

	public void disable() {
		disabled = true;
	}

	public void addConnector(WarpPipeNode pipe, ConComp con) {
		pipe.cons[con.side] = con;
		this.addConnector(con);
		if (con instanceof IObjLink) pipe.markDirty();
		if (!pipe.tile.invalid()) Utils.notifyNeighborTile((TileEntity)pipe.tile, EnumFacing.VALUES[con.side]);
	}

	public ConComp remConnector(WarpPipeNode pipe, byte side) {
		pipe.con[side] = 0;
		ConComp con = pipe.cons[side];
		remConnector(con);
		pipe.cons[side] = null;
		pipe.markDirty();
		pipe.hasFilters &= ~(1 << side);
		((BaseTileEntity)pipe.tile).markUpdate();
		if (!pipe.tile.invalid()) Utils.notifyNeighborTile((TileEntity)pipe.tile, EnumFacing.VALUES[con.side]);
		return con;
	}

	public void reorder(ConComp con) {
		if (con instanceof IItemDest) sort |= SID;
		if (con instanceof IFluidDest) sort |= SFD;
		if (con instanceof IItemSrc) sort |= SIS;
		if (con instanceof IFluidSrc) sort |= SFS;
	}

	private void addConnector(ConComp con) {
		if (con instanceof ITickable) activeCon.add((ITickable)con);
		if (con instanceof IItemDest) itemDest.add((IItemDest)con);
		if (con instanceof IFluidDest) fluidDest.add((IFluidDest)con);
		if (con instanceof IItemSrc) itemSrc.add((IItemSrc)con);
		if (con instanceof IFluidSrc) fluidSrc.add((IFluidSrc)con);
		reorder(con);
	}

	@SuppressWarnings("unlikely-arg-type")
	private void remConnector(ConComp con) {
		if (con instanceof ITickable) activeCon.remove(con);
		if (con instanceof IItemDest) itemDest.remove(con);
		if (con instanceof IFluidDest) fluidDest.remove(con);
		if (con instanceof IItemSrc) itemSrc.remove(con);
		if (con instanceof IFluidSrc) fluidSrc.remove(con);
	}

	@Override
	public void onMerged(WarpPipeNetwork network) {
		super.onMerged(network);
		activeCon.addAll(network.activeCon);
		if (!network.itemDest.isEmpty()) {
			itemDest.addAll(network.itemDest);
			sort |= SID;
		}
		if (!network.fluidDest.isEmpty()) {
			fluidDest.addAll(network.fluidDest);
			sort |= SFD;
		}
		if (!network.itemSrc.isEmpty()) {
			itemSrc.addAll(network.itemSrc);
			sort |= SIS;
		}
		if (!network.fluidSrc.isEmpty()) {
			fluidSrc.addAll(network.fluidSrc);
			sort |= SFS;
		}
	}

	@Override
	public WarpPipeNetwork onSplit(HashMap<Long, WarpPipeNode> comps) {
		WarpPipeNetwork physics = new WarpPipeNetwork(comps);
		for (Entry<Long, WarpPipeNode> e : comps.entrySet())
			for (ConComp c : e.getValue().cons)
				if (c != null) {
					remConnector(c);
					physics.addConnector(c);
				}
		return physics;
	}

	@Override
	public void remove(WarpPipeNode comp) {
		super.remove(comp);
		for (ConComp c : comp.cons)
			if (c != null)
				remConnector(c);
	}

	@Override
	public boolean tick() {
		disabled |= components.isEmpty();
		if (disabled) return false;
		if (sort != 0) {
			if ((sort & SID) != 0) Collections.sort(itemDest, destSort);
			if ((sort & SFD) != 0) Collections.sort(fluidDest, destSort);
			if ((sort & SIS) != 0) Collections.sort(itemSrc, srcSort);
			if ((sort & SFS) != 0) Collections.sort(fluidSrc, srcSort);
			sort = 0;
		}
		if (++timer >= TICKS) {
			timer = 0;
			for (ITickable con : activeCon) con.update();
		}
		return true;
	}

	/**
	 * Insert an item stack into valid destinations
	 * @param item to insert
	 * @param pr node priority to start with
	 * @return the result if not possible
	 */<commit_msg>fix mysterious non reproduceable crash<commit_after>package cd4017be.indlog.multiblock;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.function.ToIntFunction;

import org.apache.logging.log4j.Level;

import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.FMLLog;
import cd4017be.indlog.Main;
import cd4017be.lib.TickRegistry;
import cd4017be.lib.TickRegistry.ITickReceiver;
import cd4017be.lib.templates.SharedNetwork;
import cd4017be.lib.tileentity.BaseTileEntity;
import cd4017be.lib.util.Utils;

/**
 * 
 * @author CD4017BE
 *
 */
public class WarpPipeNetwork extends SharedNetwork<WarpPipeNode, WarpPipeNetwork> implements ITickReceiver {

	public static byte TICKS;
	private static final byte SID = 1, SIS = 2, SFD = 4, SFS = 8;

	public HashSet<ITickable> activeCon = new HashSet<ITickable>();
	public ArrayList<IItemDest> itemDest = new ArrayList<IItemDest>();
	public ArrayList<IFluidDest> fluidDest = new ArrayList<IFluidDest>();
	public ArrayList<IItemSrc> itemSrc = new ArrayList<IItemSrc>();
	public ArrayList<IFluidSrc> fluidSrc = new ArrayList<IFluidSrc>();
	private byte sort = 0;
	public boolean disabled = true;
	public byte timer;

	public WarpPipeNetwork(WarpPipeNode core) {
		super(core);
		for (ConComp c : core.cons)
			if (c != null)
				addConnector(c);
	}

	protected WarpPipeNetwork(HashMap<Long, WarpPipeNode> comps) {
		super(comps);
		enable();
	}

	public void enable() {
		if (disabled) {
			disabled = false;
			TickRegistry.instance.add(this);
		}
	}

	public void disable() {
		disabled = true;
	}

	public void addConnector(WarpPipeNode pipe, ConComp con) {
		pipe.cons[con.side] = con;
		this.addConnector(con);
		if (con instanceof IObjLink) pipe.markDirty();
		if (!pipe.tile.invalid()) Utils.notifyNeighborTile((TileEntity)pipe.tile, EnumFacing.VALUES[con.side]);
	}

	public ConComp remConnector(WarpPipeNode pipe, byte side) {
		pipe.con[side] = 0;
		ConComp con = pipe.cons[side];
		remConnector(con);
		pipe.cons[side] = null;
		pipe.markDirty();
		pipe.hasFilters &= ~(1 << side);
		((BaseTileEntity)pipe.tile).markUpdate();
		if (!pipe.tile.invalid()) Utils.notifyNeighborTile((TileEntity)pipe.tile, EnumFacing.VALUES[con.side]);
		return con;
	}

	public void reorder(ConComp con) {
		if (con instanceof IItemDest) sort |= SID;
		if (con instanceof IFluidDest) sort |= SFD;
		if (con instanceof IItemSrc) sort |= SIS;
		if (con instanceof IFluidSrc) sort |= SFS;
	}

	private void addConnector(ConComp con) {
		if (con instanceof ITickable) activeCon.add((ITickable)con);
		if (con instanceof IItemDest) itemDest.add((IItemDest)con);
		if (con instanceof IFluidDest) fluidDest.add((IFluidDest)con);
		if (con instanceof IItemSrc) itemSrc.add((IItemSrc)con);
		if (con instanceof IFluidSrc) fluidSrc.add((IFluidSrc)con);
		reorder(con);
	}

	@SuppressWarnings("unlikely-arg-type")
	private void remConnector(ConComp con) {
		if (con instanceof ITickable) activeCon.remove(con);
		if (con instanceof IItemDest) itemDest.remove(con);
		if (con instanceof IFluidDest) fluidDest.remove(con);
		if (con instanceof IItemSrc) itemSrc.remove(con);
		if (con instanceof IFluidSrc) fluidSrc.remove(con);
	}

	@Override
	public void onMerged(WarpPipeNetwork network) {
		super.onMerged(network);
		activeCon.addAll(network.activeCon);
		if (!network.itemDest.isEmpty()) {
			itemDest.addAll(network.itemDest);
			sort |= SID;
		}
		if (!network.fluidDest.isEmpty()) {
			fluidDest.addAll(network.fluidDest);
			sort |= SFD;
		}
		if (!network.itemSrc.isEmpty()) {
			itemSrc.addAll(network.itemSrc);
			sort |= SIS;
		}
		if (!network.fluidSrc.isEmpty()) {
			fluidSrc.addAll(network.fluidSrc);
			sort |= SFS;
		}
	}

	@Override
	public WarpPipeNetwork onSplit(HashMap<Long, WarpPipeNode> comps) {
		WarpPipeNetwork physics = new WarpPipeNetwork(comps);
		for (Entry<Long, WarpPipeNode> e : comps.entrySet())
			for (ConComp c : e.getValue().cons)
				if (c != null) {
					remConnector(c);
					physics.addConnector(c);
				}
		return physics;
	}

	@Override
	public void remove(WarpPipeNode comp) {
		super.remove(comp);
		for (ConComp c : comp.cons)
			if (c != null)
				remConnector(c);
	}

	@Override
	public boolean tick() {
		disabled |= components.isEmpty();
		if (disabled) return false;
		if (sort != 0) {
			if ((sort & SID) != 0) Collections.sort(itemDest, destSort);
			if ((sort & SFD) != 0) Collections.sort(fluidDest, destSort);
			if ((sort & SIS) != 0) Collections.sort(itemSrc, srcSort);
			if ((sort & SFS) != 0) Collections.sort(fluidSrc, srcSort);
			sort = 0;
		}
		if (++timer >= TICKS) {
			timer = 0;
			for (ITickable con : activeCon) 
				if (((ConComp)con).pipe.invalid()) debug((ConComp)con);
				else con.update();
		}
		return true;
	}

	private void debug(ConComp c) {
		ArrayList<WarpPipeNode> err = new ArrayList<WarpPipeNode>();
		for (WarpPipeNode n : components.values())
			if (n.network != this) err.add(n);
		FMLLog.log(Main.ID, Level.ERROR, "INVALID-ConComp on side %d of %s ticked in network:\nComps %d\nErrored pipes: %s", c.side, c.pipe, components.size(), err);
	}

	/**
	 * Insert an item stack into valid destinations
	 * @param item to insert
	 * @param pr node priority to start with
	 * @return the result if not possible
	 */
{'fraction_non_alphanumeric': 0.13110857577486215, 'fraction_numerical': 0.008461684730937441, 'mean_word_length': 4.536315789473684, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6740389', 'n_tokens_mistral': 3979, 'n_tokens_neox': 3658, 'n_words': 852}