/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.techhider.legacy;

import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.entity.Player;

import java.util.ArrayList;
import java.util.function.BiFunction;

@Deprecated
public class ProtocolWrapper {
    public static final ProtocolWrapper impl = new ProtocolWrapper();

    public BiFunction<Player, ClientboundSectionBlocksUpdatePacket, ClientboundSectionBlocksUpdatePacket> multiBlockChangeGenerator(TechHider techHider) {
        return (p, packet) -> {
            TechHider.LocationEvaluator locationEvaluator = techHider.getLocationEvaluator();
            SectionPos chunkCoords = packet.sectionPos;
            int chunkX = chunkCoords.getX();
            int chunkY = chunkCoords.getY();
            int chunkZ = chunkCoords.getZ();
            if (locationEvaluator.skipChunkSection(p, chunkX, chunkY, chunkZ)) {
                return packet;
            }

            packet = TechHider.multiBlockChangeCloner.apply(packet);
            final short[] oldPos = packet.positions;
            final BlockState[] oldBlocks = packet.states;
            ArrayList<Short> poss = new ArrayList<>(oldPos.length);
            ArrayList<BlockState> blocks = new ArrayList<>(oldPos.length);
            for (int i = 0; i < oldPos.length; i++) {
                short pos = oldPos[i];
                BlockState block = oldBlocks[i];
                switch (locationEvaluator.check(p, 16 * chunkX + (pos >> 8 & 0xF), 16 * chunkY + (pos & 0xF), 16 * chunkZ + (pos >> 4 & 0xF))) {
                    case SKIP:
                        poss.add(pos);
                        blocks.add(block);
                        break;
                    case CHECK:
                        poss.add(pos);
                        blocks.add(techHider.iBlockDataHidden(block) ? (BlockState) techHider.getObfuscationTarget() : block);
                        break;
                    default:
                        break;
                }
            }

            if (blocks.isEmpty()) return null;

            short[] newPos = new short[poss.size()];
            for (int i = 0; i < newPos.length; i++) {
                newPos[i] = poss.get(i);
            }

            packet.positions = newPos;
            packet.states = blocks.toArray(BlockState[]::new);
            return packet;
        };
    }
}
