package org.cyclops.integrateddynamics.core.network;

import lombok.Getter;
import lombok.Setter;
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
import org.cyclops.integrateddynamics.GeneralConfig;
import org.cyclops.integrateddynamics.api.network.IEnergyConsumingNetworkElement;
import org.cyclops.integrateddynamics.api.network.IEnergyNetwork;
import org.cyclops.integrateddynamics.api.network.INetwork;
import org.cyclops.integrateddynamics.api.network.INetworkElement;

/**
 * A network that can hold energy.
 * @author rubensworks
 */
public class EnergyNetwork extends PositionedAddonsNetworkIngredients<Long, Boolean>
        implements IEnergyNetwork {

    @Getter
    @Setter
    private INetwork network;

    public EnergyNetwork(IngredientComponent<Long, Boolean> component) {
        super(component);
    }

    @Override
    public boolean canUpdate(INetworkElement element) {
        if(!(element instanceof IEnergyConsumingNetworkElement)) return true;
        int multiplier = GeneralConfig.energyConsumptionMultiplier;
        if(multiplier == 0) return true;
        int consumptionRate = ((IEnergyConsumingNetworkElement) element).getConsumptionRate() * multiplier;
        return getChannel(element.getChannel()).extract(consumptionRate, true) == consumptionRate;
    }

    @Override
    public void onSkipUpdate(INetworkElement element) {
        if(element instanceof IEnergyConsumingNetworkElement consumingNetworkElement) {
            consumingNetworkElement.postUpdate(getNetwork(), false);
        }
    }

    @Override
    public void postUpdate(INetworkElement element) {
        if(element instanceof IEnergyConsumingNetworkElement consumingNetworkElement) {
            int multiplier = GeneralConfig.energyConsumptionMultiplier;
            if (multiplier > 0) {
                int consumptionRate = consumingNetworkElement.getConsumptionRate() * multiplier;
                getChannel(element.getChannel()).extract(consumptionRate, false);
            }
            consumingNetworkElement.postUpdate(getNetwork(), true);
        }
    }

    @Override
    public int getConsumptionRate() {
        int multiplier = GeneralConfig.energyConsumptionMultiplier;
        if(multiplier == 0) return 0;
        int consumption = 0;
        for(INetworkElement element : getNetwork().getElements()) {
            consumption += ((IEnergyConsumingNetworkElement) element).getConsumptionRate() * multiplier;
        }
        return consumption;
    }

    @Override
    public long getRateLimit() {
        return GeneralConfig.energyRateLimit;
    }
}
