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

package com.hypixel.hytale.logger.backend;

import java.util.List;
import java.util.function.Consumer;
import java.util.Objects;
import java.util.Collection;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import javax.annotation.Nonnull;
import java.nio.file.Path;
import java.io.IOException;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.time.temporal.TemporalAccessor;
import java.time.LocalDateTime;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Paths;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.Nullable;
import java.util.logging.FileHandler;
import java.util.logging.LogRecord;
import java.util.concurrent.BlockingQueue;
import java.time.format.DateTimeFormatter;

public class HytaleFileHandler extends Thread
{
    public static final DateTimeFormatter LOG_FILE_DATE_FORMAT;
    public static final HytaleFileHandler INSTANCE;
    private final BlockingQueue<LogRecord> logRecords;
    @Nullable
    private FileHandler fileHandler;
    
    public HytaleFileHandler() {
        super("HytaleLogger");
        this.logRecords = new LinkedBlockingQueue<LogRecord>();
        this.setDaemon(true);
    }
    
    @Override
    public void run() {
        if (this.fileHandler == null) {
            throw new IllegalStateException("Thread should not be started when no file handler exists!");
        }
        try {
            while (!this.isInterrupted()) {
                this.fileHandler.publish(this.logRecords.take());
            }
        }
        catch (final InterruptedException ignored) {
            Thread.currentThread().interrupt();
        }
    }
    
    @Nullable
    public FileHandler getFileHandler() {
        return this.fileHandler;
    }
    
    public void enable() {
        if (this.fileHandler != null) {
            throw new IllegalStateException("Already enabled!");
        }
        try {
            final Path logsDirectory = Paths.get("logs/", new String[0]);
            if (!Files.isDirectory(logsDirectory, new LinkOption[0])) {
                Files.createDirectory(logsDirectory, (FileAttribute<?>[])new FileAttribute[0]);
            }
            final String fileNamePart = "logs/" + HytaleFileHandler.LOG_FILE_DATE_FORMAT.format(LocalDateTime.now());
            String fileName = fileNamePart + "_server.log";
            if (Files.exists(Paths.get(fileName, new String[0]), new LinkOption[0])) {
                fileName = fileNamePart + "%u_server.log";
            }
            (this.fileHandler = new FileHandler(fileName)).setEncoding("UTF-8");
            this.fileHandler.setLevel(Level.ALL);
            this.fileHandler.setFormatter(new HytaleLogFormatter(() -> false));
        }
        catch (final IOException e) {
            throw new RuntimeException("Failed to create file handler!", e);
        }
        this.start();
    }
    
    public void log(@Nonnull final LogRecord logRecord) {
        if (!this.isAlive()) {
            if (this.fileHandler != null) {
                this.fileHandler.publish(logRecord);
            }
            return;
        }
        this.logRecords.add(logRecord);
    }
    
    public void shutdown() {
        if (this.fileHandler != null) {
            this.interrupt();
            try {
                this.join();
            }
            catch (final InterruptedException ignored) {
                Thread.currentThread().interrupt();
            }
            final List<LogRecord> list = new ObjectArrayList<LogRecord>();
            this.logRecords.drainTo(list);
            final List<LogRecord> list2 = list;
            final FileHandler fileHandler = this.fileHandler;
            Objects.requireNonNull(fileHandler);
            list2.forEach(fileHandler::publish);
            this.fileHandler.flush();
            this.fileHandler.close();
            this.fileHandler = null;
        }
    }
    
    static {
        LOG_FILE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
        INSTANCE = new HytaleFileHandler();
    }
}
