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.dimension.DimensionType;
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) {
        this.fixerUpper = dataFixer;
        this.worker = new IOWorker(new RegionFileStorage(file), "chunk");
    }
    
    public CompoundTag upgradeChunkTag(final DimensionType cbi, final Supplier<DimensionDataStorage> supplier, CompoundTag jt) {
        final int integer5 = getVersion(jt);
        final int integer6 = 1493;
        if (integer5 < 1493) {
            jt = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, jt, integer5, 1493);
            if (jt.getCompound("Level").getBoolean("hasLegacyStructureData")) {
                if (this.legacyStructureHandler == null) {
                    this.legacyStructureHandler = LegacyStructureDataHandler.getLegacyStructureHandler(cbi, supplier.get());
                }
                jt = this.legacyStructureHandler.updateFromLegacy(jt);
            }
        }
        jt = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, jt, Math.max(1493, integer5));
        if (integer5 < SharedConstants.getCurrentVersion().getWorldVersion()) {
            jt.putInt("DataVersion", SharedConstants.getCurrentVersion().getWorldVersion());
        }
        return jt;
    }
    
    public static int getVersion(final CompoundTag jt) {
        return jt.contains("DataVersion", 99) ? jt.getInt("DataVersion") : -1;
    }
    
    @Nullable
    public CompoundTag read(final ChunkPos bjh) throws IOException {
        return this.worker.load(bjh);
    }
    
    public void write(final ChunkPos bjh, final CompoundTag jt) {
        this.worker.store(bjh, jt);
        if (this.legacyStructureHandler != null) {
            this.legacyStructureHandler.removeIndex(bjh.toLong());
        }
    }
    
    public void flushWorker() {
        this.worker.synchronize().join();
    }
    
    @Override
    public void close() throws IOException {
        this.worker.close();
    }
}
