/*
 *   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.core;

import de.steamwar.Reflection;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.minecraft.SystemUtils;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.world.level.EnumGamemode;
import org.bukkit.GameMode;

import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.function.LongSupplier;

public class ProtocolWrapper19 implements ProtocolWrapper {

    private static final Reflection.Field<List> equipmentStack = Reflection.getField(equipmentPacket, List.class, 0);
    @Override
    public void setEquipmentPacketStack(Object packet, Object slot, Object stack) {
        equipmentStack.set(packet, Collections.singletonList(new Pair<>(slot, stack)));
    }

    private static final Reflection.Constructor removePacketConstructor = Reflection.getConstructor(ClientboundPlayerInfoRemovePacket.class, List.class);
    private static final Reflection.Field<EnumSet> updateActions = Reflection.getField(ClientboundPlayerInfoUpdatePacket.class, EnumSet.class, 0);
    private static final Reflection.Field<List> updatePlayers = Reflection.getField(ClientboundPlayerInfoUpdatePacket.class, List.class, 0);

    @Override
    @SuppressWarnings("deprecation")
    public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) {
        if(action == PlayerInfoAction.REMOVE)
            return removePacketConstructor.invoke(Collections.singletonList(profile.getId()));

        Object packet = Reflection.newInstance(ClientboundPlayerInfoUpdatePacket.class);
        updateActions.set(packet, action == PlayerInfoAction.ADD ? EnumSet.of(ClientboundPlayerInfoUpdatePacket.a.a, ClientboundPlayerInfoUpdatePacket.a.c) : EnumSet.of(ClientboundPlayerInfoUpdatePacket.a.c));
        updatePlayers.set(packet, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.b(profile.getId(), profile, false, 0, EnumGamemode.a(mode.getValue()), null, null)));
        return packet;
    }

    @Override
    public void initTPSWarp(LongSupplier longSupplier) {
        SystemUtils.a = () -> System.nanoTime() + longSupplier.getAsLong();
    }
}
