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

package com.hypixel.hytale.server.core.util.io;

import javax.annotation.Nonnull;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.io.Reader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ByteArrayInputStream;
import java.io.Writer;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.ByteArrayOutputStream;
import joptsimple.OptionSpec;
import com.hypixel.hytale.server.core.Options;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.nio.file.Path;
import java.util.concurrent.locks.ReadWriteLock;

public abstract class BlockingDiskFile
{
    protected final ReadWriteLock fileLock;
    protected final Path path;
    
    public BlockingDiskFile(final Path path) {
        this.fileLock = new ReentrantReadWriteLock();
        this.path = path;
    }
    
    protected abstract void read(final BufferedReader p0) throws IOException;
    
    protected abstract void write(final BufferedWriter p0) throws IOException;
    
    protected abstract void create(final BufferedWriter p0) throws IOException;
    
    public void syncLoad() {
        this.fileLock.writeLock().lock();
        try {
            final File file = this.toLocalFile();
            try {
                if (!file.exists()) {
                    if (Options.getOptionSet().has(Options.BARE)) {
                        byte[] bytes;
                        try (final ByteArrayOutputStream out = new ByteArrayOutputStream();
                             final BufferedWriter buf = new BufferedWriter(new OutputStreamWriter(out))) {
                            this.create(buf);
                            bytes = out.toByteArray();
                        }
                        try (final BufferedReader buf2 = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)))) {
                            this.read(buf2);
                        }
                        return;
                    }
                    try (final BufferedWriter fileWriter = Files.newBufferedWriter(file.toPath(), new OpenOption[0])) {
                        this.create(fileWriter);
                    }
                }
                try (final BufferedReader fileReader = Files.newBufferedReader(file.toPath())) {
                    this.read(fileReader);
                }
            }
            catch (final Exception ex) {
                throw new RuntimeException("Failed to syncLoad() " + file.getAbsolutePath(), (Throwable)ex);
            }
        }
        finally {
            this.fileLock.writeLock().unlock();
        }
    }
    
    public void syncSave() {
        File file = null;
        this.fileLock.readLock().lock();
        try {
            file = this.toLocalFile();
            try (final BufferedWriter fileWriter = Files.newBufferedWriter(file.toPath(), new OpenOption[0])) {
                this.write(fileWriter);
            }
        }
        catch (final Exception ex) {
            throw new RuntimeException("Failed to syncSave() " + ((file != null) ? file.getAbsolutePath() : null), (Throwable)ex);
        }
        finally {
            this.fileLock.readLock().unlock();
        }
    }
    
    @Nonnull
    protected File toLocalFile() {
        return this.path.toFile();
    }
}
