package net.minecraft.world.level.chunk.storage;

import java.io.IOException;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.SharedConstants;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.storage.DimensionDataStorage;
import java.util.function.Supplier;
import net.minecraft.world.level.Level;
import net.minecraft.resources.ResourceKey;
import java.io.File;
import javax.annotation.Nullable;
import net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler;
import com.mojang.datafixers.DataFixer;

public class ChunkStorage implements AutoCloseable {
    private final IOWorker worker;
    protected final DataFixer fixerUpper;
    @Nullable
    private LegacyStructureDataHandler legacyStructureHandler;
    
    public ChunkStorage(final File file, final DataFixer dataFixer, final boolean boolean3) {
        this.fixerUpper = dataFixer;
        this.worker = new IOWorker(file, boolean3, "chunk");
    }
    
    public CompoundTag upgradeChunkTag(final ResourceKey<Level> ug, final Supplier<DimensionDataStorage> supplier, CompoundTag le) {
        final int integer5 = getVersion(le);
        final int integer6 = 1493;
        if (integer5 < 1493) {
            le = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, le, integer5, 1493);
            if (le.getCompound("Level").getBoolean("hasLegacyStructureData")) {
                if (this.legacyStructureHandler == null) {
                    this.legacyStructureHandler = LegacyStructureDataHandler.getLegacyStructureHandler(ug, supplier.get());
                }
                le = this.legacyStructureHandler.updateFromLegacy(le);
            }
        }
        le = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, le, Math.max(1493, integer5));
        if (integer5 < SharedConstants.getCurrentVersion().getWorldVersion()) {
            le.putInt("DataVersion", SharedConstants.getCurrentVersion().getWorldVersion());
        }
        return le;
    }
    
    public static int getVersion(final CompoundTag le) {
        return le.contains("DataVersion", 99) ? le.getInt("DataVersion") : -1;
    }
    
    @Nullable
    public CompoundTag read(final ChunkPos bph) throws IOException {
        return this.worker.load(bph);
    }
    
    public void write(final ChunkPos bph, final CompoundTag le) {
        this.worker.store(bph, le);
        if (this.legacyStructureHandler != null) {
            this.legacyStructureHandler.removeIndex(bph.toLong());
        }
    }
    
    public void flushWorker() {
        this.worker.synchronize().join();
    }
    
    @Override
    public void close() throws IOException {
        this.worker.close();
    }
}
