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

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

import com.hypixel.hytale.server.npc.decisionmaker.core.Evaluator;
import com.hypixel.hytale.server.npc.decisionmaker.core.EvaluationContext;
import com.hypixel.hytale.server.npc.role.support.StateSupport;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.npc.decisionmaker.stateevaluator.StateOption;
import java.util.logging.Level;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.dependency.SystemDependency;
import com.hypixel.hytale.component.dependency.Order;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.dependency.Dependency;
import java.util.Set;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.npc.decisionmaker.stateevaluator.StateEvaluator;
import com.hypixel.hytale.component.ComponentType;
import javax.annotation.Nonnull;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;

public class StateEvaluatorSystem extends EntityTickingSystem<EntityStore>
{
    @Nonnull
    private static final HytaleLogger LOGGER;
    @Nonnull
    private final ComponentType<EntityStore, StateEvaluator> stateEvaluatorComponent;
    @Nonnull
    private final ComponentType<EntityStore, NPCEntity> npcComponentType;
    @Nonnull
    private final ComponentType<EntityStore, UUIDComponent> uuidComponentType;
    @Nonnull
    private final Set<Dependency<EntityStore>> dependencies;
    @Nonnull
    private final Query<EntityStore> query;
    
    public StateEvaluatorSystem(@Nonnull final ComponentType<EntityStore, StateEvaluator> stateEvaluatorComponent, @Nonnull final ComponentType<EntityStore, NPCEntity> npcComponentType) {
        this.uuidComponentType = UUIDComponent.getComponentType();
        this.stateEvaluatorComponent = stateEvaluatorComponent;
        this.npcComponentType = npcComponentType;
        this.dependencies = (Set<Dependency<EntityStore>>)Set.of(new SystemDependency(Order.BEFORE, RoleSystems.BehaviourTickSystem.class), new SystemDependency(Order.AFTER, RoleSystems.PreBehaviourSupportTickSystem.class));
        this.query = (Query<EntityStore>)Query.and(npcComponentType, stateEvaluatorComponent, this.uuidComponentType);
    }
    
    @Nonnull
    @Override
    public Set<Dependency<EntityStore>> getDependencies() {
        return this.dependencies;
    }
    
    @Override
    public boolean isParallel(final int archetypeChunkSize, final int taskCount) {
        return EntityTickingSystem.maybeUseParallel(archetypeChunkSize, taskCount);
    }
    
    @Nonnull
    @Override
    public Query<EntityStore> getQuery() {
        return this.query;
    }
    
    @Override
    public void tick(final float dt, final int index, @Nonnull final ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        final NPCEntity npcComponent = archetypeChunk.getComponent(index, this.npcComponentType);
        assert npcComponent != null;
        final UUIDComponent uuidComponent = archetypeChunk.getComponent(index, this.uuidComponentType);
        assert uuidComponent != null;
        final Role role = npcComponent.getRole();
        if (role == null) {
            return;
        }
        final StateSupport stateSupport = role.getStateSupport();
        if (stateSupport.isRunningTransitionActions()) {
            return;
        }
        final StateEvaluator stateEvaluator = archetypeChunk.getComponent(index, this.stateEvaluatorComponent);
        assert stateEvaluator != null;
        if (!stateEvaluator.isActive() || !stateEvaluator.shouldExecute(dt)) {
            return;
        }
        HytaleLogger.Api logContext = StateEvaluatorSystem.LOGGER.at(Level.FINE);
        if (logContext.isEnabled()) {
            logContext.log("%s with uuid %s: Beginning state evaluation", npcComponent.getRoleName(), uuidComponent.getUuid());
        }
        final EvaluationContext evaluationContext = stateEvaluator.getEvaluationContext();
        stateEvaluator.prepareEvaluationContext(evaluationContext);
        final Evaluator.OptionHolder chosenOption = stateEvaluator.evaluate(index, archetypeChunk, commandBuffer, evaluationContext);
        evaluationContext.reset();
        logContext = StateEvaluatorSystem.LOGGER.at(Level.FINE);
        if (logContext.isEnabled()) {
            logContext.log("%s with uuid %s: Chose state option %s", npcComponent.getRoleName(), uuidComponent.getUuid(), chosenOption);
        }
        if (chosenOption == null) {
            return;
        }
        final StateOption action = chosenOption.getOption();
        final int targetState = action.getStateIndex();
        final int targetSubState = action.getSubStateIndex();
        if (!stateSupport.inState(targetState) || !stateSupport.inSubState(targetSubState)) {
            stateSupport.setState(action.getStateIndex(), action.getSubStateIndex(), true, false);
            logContext = StateEvaluatorSystem.LOGGER.at(Level.FINE);
            if (logContext.isEnabled()) {
                logContext.log("%s with uuid %s: Setting state", npcComponent.getRoleName(), uuidComponent.getUuid());
            }
            stateEvaluator.onStateSwitched();
        }
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
    }
}
