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

import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.io.DataOutputStream;
import java.io.DataOutput;
import javax.annotation.Nullable;
import java.io.DataInputStream;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.CompoundTag;
import java.io.IOException;
import net.minecraft.world.level.ChunkPos;
import java.io.File;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;

public final class RegionFileStorage implements AutoCloseable {
    private final Long2ObjectLinkedOpenHashMap<RegionFile> regionCache;
    private final File folder;
    
    RegionFileStorage(final File file) {
        this.regionCache = (Long2ObjectLinkedOpenHashMap<RegionFile>)new Long2ObjectLinkedOpenHashMap();
        this.folder = file;
    }
    
    private RegionFile getRegionFile(final ChunkPos bjh) throws IOException {
        final long long3 = ChunkPos.asLong(bjh.getRegionX(), bjh.getRegionZ());
        final RegionFile cbc5 = (RegionFile)this.regionCache.getAndMoveToFirst(long3);
        if (cbc5 != null) {
            return cbc5;
        }
        if (this.regionCache.size() >= 256) {
            ((RegionFile)this.regionCache.removeLast()).close();
        }
        if (!this.folder.exists()) {
            this.folder.mkdirs();
        }
        final File file6 = new File(this.folder, "r." + bjh.getRegionX() + "." + bjh.getRegionZ() + ".mca");
        final RegionFile cbc6 = new RegionFile(file6, this.folder);
        this.regionCache.putAndMoveToFirst(long3, cbc6);
        return cbc6;
    }
    
    @Nullable
    public CompoundTag read(final ChunkPos bjh) throws IOException {
        final RegionFile cbc3 = this.getRegionFile(bjh);
        try (final DataInputStream dataInputStream4 = cbc3.getChunkDataInputStream(bjh)) {
            if (dataInputStream4 == null) {
                return null;
            }
            return NbtIo.read(dataInputStream4);
        }
    }
    
    protected void write(final ChunkPos bjh, final CompoundTag jt) throws IOException {
        final RegionFile cbc4 = this.getRegionFile(bjh);
        try (final DataOutputStream dataOutputStream5 = cbc4.getChunkDataOutputStream(bjh)) {
            NbtIo.write(jt, dataOutputStream5);
        }
    }
    
    @Override
    public void close() throws IOException {
        for (final RegionFile cbc3 : this.regionCache.values()) {
            cbc3.close();
        }
    }
}
