// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.npc.commands;

import com.hypixel.hytale.server.core.command.system.arguments.system.Argument;
import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import com.hypixel.hytale.server.npc.util.IAnnotatedComponentCollection;
import java.util.Iterator;
import java.util.List;
import com.hypixel.hytale.server.npc.role.Role;
import java.util.logging.Level;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.hypixel.hytale.server.npc.util.IAnnotatedComponent;
import com.hypixel.hytale.server.npc.util.ComponentInfo;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;

public class NPCDumpCommand extends NPCWorldCommandBase
{
    @Nonnull
    private final FlagArg jsonArg;
    
    public NPCDumpCommand() {
        super("dump", "server.commands.npc.dump.desc");
        this.jsonArg = this.withFlagArg("json", "server.commands.npc.dump.json");
    }
    
    @Override
    protected void execute(@Nonnull final CommandContext context, @Nonnull final NPCEntity npc, @Nonnull final World world, @Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref) {
        final StringBuilder sb = new StringBuilder(npc.getRoleName());
        sb.append(":\n");
        final Role role = npc.getRole();
        if (role != null) {
            if (!((Argument<Arg, Boolean>)this.jsonArg).get(context)) {
                final List<ComponentInfo> componentInfoList = new ObjectArrayList<ComponentInfo>();
                dumpComponent(role, role, -1, 0, componentInfoList);
                for (final ComponentInfo info : componentInfoList) {
                    sb.append(info).append('\n');
                }
            }
            else {
                final JsonObject obj = new JsonObject();
                dumpComponentsAsJson(role, role, -1, 0, obj);
                sb.append(obj);
            }
        }
        NPCPlugin.get().getLogger().at(Level.INFO).log(sb.toString());
    }
    
    private static void dumpComponent(@Nonnull final Role role, @Nonnull final IAnnotatedComponent component, final int index, final int nestingDepth, @Nonnull final List<ComponentInfo> infoList) {
        final ComponentInfo componentInfo = new ComponentInfo(component.getClass().getSimpleName(), index, nestingDepth);
        infoList.add(componentInfo);
        if (component instanceof final IAnnotatedComponentCollection aggregate) {
            for (int nestedComponentCount = aggregate.componentCount(), i = 0; i < nestedComponentCount; ++i) {
                final IAnnotatedComponent nestedComponent = aggregate.getComponent(i);
                if (nestedComponent != null) {
                    dumpComponent(role, nestedComponent, i, nestingDepth + 1, infoList);
                }
            }
        }
        component.getInfo(role, componentInfo);
    }
    
    private static void dumpComponentsAsJson(@Nonnull final Role role, @Nonnull final IAnnotatedComponent component, final int index, final int nestingDepth, @Nonnull final JsonElement parent) {
        final ComponentInfo componentInfo = new ComponentInfo(component.getClass().getSimpleName(), index, nestingDepth);
        final JsonObject object = parent.isJsonObject() ? parent.getAsJsonObject() : new JsonObject();
        object.add("name", new JsonPrimitive(componentInfo.getName()));
        if (componentInfo.getIndex() >= 0) {
            object.add("index", new JsonPrimitive(componentInfo.getIndex()));
        }
        if (component instanceof final IAnnotatedComponentCollection aggregate) {
            final JsonArray array = new JsonArray();
            object.add("children", array);
            for (int nestedComponentCount = aggregate.componentCount(), i = 0; i < nestedComponentCount; ++i) {
                final IAnnotatedComponent nestedComponent = aggregate.getComponent(i);
                if (nestedComponent != null) {
                    dumpComponentsAsJson(role, nestedComponent, i, nestingDepth + 1, array);
                }
            }
        }
        component.getInfo(role, componentInfo);
        final List<String> fields = componentInfo.getFields();
        if (!fields.isEmpty()) {
            final JsonArray array = new JsonArray();
            for (final String field : fields) {
                array.add(field);
            }
            object.add("parameters", array);
        }
        if (parent.isJsonArray()) {
            parent.getAsJsonArray().add(object);
        }
    }
}
