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

package com.hypixel.hytale.builtin.portals.integrations;

import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
import javax.annotation.Nonnull;
import java.time.Instant;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.component.Store;
import java.time.temporal.Temporal;
import java.time.Duration;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.builtin.instances.removal.InstanceDataResource;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.builtin.instances.removal.TimeoutCondition;
import com.hypixel.hytale.builtin.instances.removal.WorldEmptyCondition;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.builtin.instances.removal.RemovalCondition;

public class PortalRemovalCondition implements RemovalCondition
{
    public static final BuilderCodec<PortalRemovalCondition> CODEC;
    private final WorldEmptyCondition worldEmptyCondition;
    private TimeoutCondition timeLimitCondition;
    
    public PortalRemovalCondition() {
        this(60.0);
    }
    
    public PortalRemovalCondition(final double timeLimitSeconds) {
        this.worldEmptyCondition = new WorldEmptyCondition(90.0);
        this.timeLimitCondition = new TimeoutCondition(timeLimitSeconds);
    }
    
    private double getTimeLimitSeconds() {
        return this.timeLimitCondition.getTimeoutSeconds();
    }
    
    private void setTimeLimitSeconds(final double timeLimitSeconds) {
        this.timeLimitCondition = new TimeoutCondition(timeLimitSeconds);
    }
    
    public double getElapsedSeconds(final World world) {
        final double timeLimitSeconds = this.timeLimitCondition.getTimeoutSeconds();
        final double remainingSeconds = this.getRemainingSeconds(world);
        return Math.max(0.0, timeLimitSeconds - remainingSeconds);
    }
    
    public double getRemainingSeconds(final World world) {
        final Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
        final Store<EntityStore> entityStore = world.getEntityStore().getStore();
        final InstanceDataResource instanceData = chunkStore.getResource(InstanceDataResource.getResourceType());
        final TimeResource timeResource = entityStore.getResource(TimeResource.getResourceType());
        final Instant timeoutInstant = instanceData.getTimeoutTimer();
        if (timeoutInstant == null) {
            return this.timeLimitCondition.getTimeoutSeconds();
        }
        final double remainingSeconds = Duration.between(timeResource.getNow(), timeoutInstant).toNanos() / 1.0E9;
        return Math.max(0.0, remainingSeconds);
    }
    
    public void setRemainingSeconds(final World world, double seconds) {
        seconds = Math.max(0.0, seconds);
        final Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
        final Store<EntityStore> entityStore = world.getEntityStore().getStore();
        final InstanceDataResource instanceData = chunkStore.getResource(InstanceDataResource.getResourceType());
        final TimeResource timeResource = entityStore.getResource(TimeResource.getResourceType());
        instanceData.setTimeoutTimer(timeResource.getNow().plusMillis((long)(seconds * 1000.0)));
    }
    
    @Override
    public boolean shouldRemoveWorld(@Nonnull final Store<ChunkStore> store) {
        final InstanceDataResource instanceData = store.getResource(InstanceDataResource.getResourceType());
        return (instanceData.hadPlayer() && this.timeLimitCondition.shouldRemoveWorld(store)) || this.worldEmptyCondition.shouldRemoveWorld(store);
    }
    
    static {
        CODEC = BuilderCodec.builder(PortalRemovalCondition.class, PortalRemovalCondition::new).documentation("A condition for temporary portal worlds.").append(new KeyedCodec("TimeoutSeconds", Codec.DOUBLE), (o, i) -> o.setTimeLimitSeconds(i), o -> o.getTimeLimitSeconds()).documentation("How long the portal world will stay open (in seconds) after being joined.").add().build();
    }
}
