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

package com.hypixel.hytale.server.core.modules.i18n.commands;

import com.hypixel.hytale.server.core.command.system.arguments.system.Argument;
import java.util.HashSet;
import java.io.BufferedWriter;
import java.nio.file.OpenOption;
import java.nio.file.attribute.FileAttribute;
import java.util.Set;
import java.util.Collection;
import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Properties;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.util.Iterator;
import java.nio.file.Path;
import com.hypixel.hytale.assetstore.AssetPack;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import java.util.logging.Level;
import com.hypixel.hytale.server.core.modules.i18n.I18nModule;
import java.util.Map;
import com.hypixel.hytale.event.IEvent;
import com.hypixel.hytale.server.core.modules.i18n.event.GenerateDefaultLanguageEvent;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.modules.i18n.generator.TranslationMap;
import java.util.concurrent.ConcurrentHashMap;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.AssetModule;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncCommand;

public class GenerateI18nCommand extends AbstractAsyncCommand
{
    public static final HytaleLogger LOGGER;
    protected final FlagArg cleanArg;
    
    public GenerateI18nCommand() {
        super("gen", "server.commands.i18n.gen.desc");
        this.cleanArg = this.withFlagArg("clean", "server.commands.i18n.gen.clean.desc");
    }
    
    @Nonnull
    @Override
    protected CompletableFuture<Void> executeAsync(@Nonnull final CommandContext context) {
        final CommandSender commandSender = context.sender();
        final AssetPack baseAssetPack = AssetModule.get().getBaseAssetPack();
        if (baseAssetPack.isImmutable()) {
            commandSender.sendMessage(Message.translation("server.commands.i18n.gen.immutable"));
            return CompletableFuture.completedFuture((Void)null);
        }
        final Path baseAssetPackRoot = baseAssetPack.getRoot();
        final boolean cleanOldKeys = ((Argument<Arg, Boolean>)this.cleanArg).get(context);
        final ConcurrentHashMap<String, TranslationMap> translationFiles = new ConcurrentHashMap<String, TranslationMap>();
        HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<Void>>)GenerateDefaultLanguageEvent.class).dispatch(new GenerateDefaultLanguageEvent(translationFiles));
        return CompletableFuture.runAsync(() -> {
            try {
                for (Map.Entry<String, TranslationMap> entry : translationFiles.entrySet()) {
                    final String filename = entry.getKey();
                    final TranslationMap generatedMap = entry.getValue();
                    final Path path = baseAssetPackRoot.resolve(I18nModule.DEFAULT_GENERATED_PATH).resolve(filename + ".lang");
                    final TranslationMap mergedMap = this.mergei18nWithOnDisk(path, generatedMap, cleanOldKeys);
                    mergedMap.sortByKeyBeforeFirstDot();
                    this.writeTranslationMap(path, mergedMap);
                    GenerateI18nCommand.LOGGER.at(Level.INFO).log("Wrote %s translation(s) to %s", mergedMap.size(), path.toAbsolutePath());
                }
                GenerateI18nCommand.LOGGER.at(Level.INFO).log("Wrote %s generated translation file(s)", translationFiles.size());
                commandSender.sendMessage(Message.translation(cleanOldKeys ? "server.commands.i18n.gen.cleaned" : "server.commands.i18n.gen.done"));
            }
            catch (final Throwable t) {
                throw new RuntimeException("Error writing generated translation file(s)", t);
            }
        });
    }
    
    @Nonnull
    private TranslationMap mergei18nWithOnDisk(@Nonnull final Path path, @Nonnull final TranslationMap generated, final boolean cleanOldKeys) throws Exception {
        final TranslationMap mergedMap = new TranslationMap();
        if (Files.exists(path, new LinkOption[0])) {
            final Properties diskAsProperties = new Properties();
            diskAsProperties.load(new FileInputStream(path.toFile()));
            final TranslationMap diskTranslationMap = new TranslationMap(diskAsProperties);
            if (cleanOldKeys) {
                final Set<String> extraneousDiskKeys = difference(diskTranslationMap.asMap().keySet(), generated.asMap().keySet());
                diskTranslationMap.removeKeys(extraneousDiskKeys);
            }
            mergedMap.putAbsentKeys(diskTranslationMap);
        }
        mergedMap.putAbsentKeys(generated);
        return mergedMap;
    }
    
    private void writeTranslationMap(@Nonnull final Path path, @Nonnull final TranslationMap translationMap) throws Exception {
        Files.createDirectories(path.getParent(), (FileAttribute<?>[])new FileAttribute[0]);
        final Map<String, String> map = translationMap.asMap();
        try (final BufferedWriter writer = Files.newBufferedWriter(path, new OpenOption[0])) {
            for (final Map.Entry<String, String> e : map.entrySet()) {
                final String k = e.getKey();
                final String v = e.getValue();
                writer.write(k);
                writer.write(" = ");
                writer.write(v);
                writer.write(System.lineSeparator());
            }
        }
    }
    
    @Nonnull
    private static <T> Set<T> difference(@Nonnull final Set<T> a, @Nonnull final Set<T> b) {
        final Set<T> difference = new HashSet<T>((Collection<? extends T>)a);
        difference.removeAll(b);
        return difference;
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
    }
}
