package net.minecraft.world.entity.ai.behavior;

import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import java.util.Map;
import net.minecraft.world.entity.LivingEntity;

public abstract class Behavior<E extends LivingEntity> {
    private final Map<MemoryModuleType<?>, MemoryStatus> entryCondition;
    private Status status;
    private long endTimestamp;
    private final int minDuration;
    private final int maxDuration;
    
    public Behavior(final Map<MemoryModuleType<?>, MemoryStatus> map) {
        this(map, 60);
    }
    
    public Behavior(final Map<MemoryModuleType<?>, MemoryStatus> map, final int integer) {
        this(map, integer, integer);
    }
    
    public Behavior(final Map<MemoryModuleType<?>, MemoryStatus> map, final int integer2, final int integer3) {
        this.status = Status.STOPPED;
        this.minDuration = integer2;
        this.maxDuration = integer3;
        this.entryCondition = map;
    }
    
    public Status getStatus() {
        return this.status;
    }
    
    public final boolean tryStart(final ServerLevel xd, final E akz, final long long3) {
        if (this.hasRequiredMemories(akz) && this.checkExtraStartConditions(xd, akz)) {
            this.status = Status.RUNNING;
            final int integer6 = this.minDuration + xd.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
            this.endTimestamp = long3 + integer6;
            this.start(xd, akz, long3);
            return true;
        }
        return false;
    }
    
    protected void start(final ServerLevel xd, final E akz, final long long3) {
    }
    
    public final void tickOrStop(final ServerLevel xd, final E akz, final long long3) {
        if (!this.timedOut(long3) && this.canStillUse(xd, akz, long3)) {
            this.tick(xd, akz, long3);
        }
        else {
            this.doStop(xd, akz, long3);
        }
    }
    
    protected void tick(final ServerLevel xd, final E akz, final long long3) {
    }
    
    public final void doStop(final ServerLevel xd, final E akz, final long long3) {
        this.status = Status.STOPPED;
        this.stop(xd, akz, long3);
    }
    
    protected void stop(final ServerLevel xd, final E akz, final long long3) {
    }
    
    protected boolean canStillUse(final ServerLevel xd, final E akz, final long long3) {
        return false;
    }
    
    protected boolean timedOut(final long long1) {
        return long1 > this.endTimestamp;
    }
    
    protected boolean checkExtraStartConditions(final ServerLevel xd, final E akz) {
        return true;
    }
    
    @Override
    public String toString() {
        return this.getClass().getSimpleName();
    }
    
    private boolean hasRequiredMemories(final E akz) {
        final MemoryModuleType<?> arl3;
        final MemoryStatus arm4;
        return this.entryCondition.entrySet().stream().allMatch(entry -> {
            arl3 = entry.getKey();
            arm4 = (MemoryStatus)entry.getValue();
            return akz.getBrain().checkMemory(arl3, arm4);
        });
    }
    
    public enum Status {
        STOPPED, 
        RUNNING;
    }
}
