package com.mojang.realmsclient.dto;

import java.util.Comparator;
import org.apache.logging.log4j.LogManager;
import org.apache.commons.lang3.builder.EqualsBuilder;
import java.util.Objects;
import com.google.gson.JsonParser;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import java.util.Locale;
import com.google.common.collect.ComparisonChain;
import com.mojang.realmsclient.util.JsonUtils;
import com.google.gson.JsonObject;
import java.util.Iterator;
import com.google.common.base.Joiner;
import com.mojang.realmsclient.util.RealmsUtil;
import net.minecraft.client.Minecraft;
import com.google.common.collect.Lists;
import java.util.Map;
import java.util.List;
import org.apache.logging.log4j.Logger;

public class RealmsServer extends ValueObject {
    private static final Logger LOGGER;
    public long id;
    public String remoteSubscriptionId;
    public String name;
    public String motd;
    public State state;
    public String owner;
    public String ownerUUID;
    public List<PlayerInfo> players;
    public Map<Integer, RealmsWorldOptions> slots;
    public boolean expired;
    public boolean expiredTrial;
    public int daysLeft;
    public WorldType worldType;
    public int activeSlot;
    public String minigameName;
    public int minigameId;
    public String minigameImage;
    public RealmsServerPing serverPing;
    
    public RealmsServer() {
        this.serverPing = new RealmsServerPing();
    }
    
    public String getDescription() {
        return this.motd;
    }
    
    public String getName() {
        return this.name;
    }
    
    public String getMinigameName() {
        return this.minigameName;
    }
    
    public void setName(final String string) {
        this.name = string;
    }
    
    public void setDescription(final String string) {
        this.motd = string;
    }
    
    public void updateServerPing(final RealmsServerPlayerList dit) {
        final List<String> list3 = Lists.newArrayList();
        int integer4 = 0;
        for (final String string6 : dit.players) {
            if (string6.equals(Minecraft.getInstance().getUser().getUuid())) {
                continue;
            }
            String string7 = "";
            try {
                string7 = RealmsUtil.uuidToName(string6);
            }
            catch (Exception exception8) {
                RealmsServer.LOGGER.error("Could not get name for " + string6, (Throwable)exception8);
                continue;
            }
            list3.add(string7);
            ++integer4;
        }
        this.serverPing.nrOfPlayers = String.valueOf(integer4);
        this.serverPing.playerList = Joiner.on('\n').join(list3);
    }
    
    public static RealmsServer parse(final JsonObject jsonObject) {
        final RealmsServer dip2 = new RealmsServer();
        try {
            dip2.id = JsonUtils.getLongOr("id", jsonObject, -1L);
            dip2.remoteSubscriptionId = JsonUtils.getStringOr("remoteSubscriptionId", jsonObject, null);
            dip2.name = JsonUtils.getStringOr("name", jsonObject, null);
            dip2.motd = JsonUtils.getStringOr("motd", jsonObject, null);
            dip2.state = getState(JsonUtils.getStringOr("state", jsonObject, State.CLOSED.name()));
            dip2.owner = JsonUtils.getStringOr("owner", jsonObject, null);
            if (jsonObject.get("players") != null && jsonObject.get("players").isJsonArray()) {
                dip2.players = parseInvited(jsonObject.get("players").getAsJsonArray());
                sortInvited(dip2);
            }
            else {
                dip2.players = Lists.newArrayList();
            }
            dip2.daysLeft = JsonUtils.getIntOr("daysLeft", jsonObject, 0);
            dip2.expired = JsonUtils.getBooleanOr("expired", jsonObject, false);
            dip2.expiredTrial = JsonUtils.getBooleanOr("expiredTrial", jsonObject, false);
            dip2.worldType = getWorldType(JsonUtils.getStringOr("worldType", jsonObject, WorldType.NORMAL.name()));
            dip2.ownerUUID = JsonUtils.getStringOr("ownerUUID", jsonObject, "");
            if (jsonObject.get("slots") != null && jsonObject.get("slots").isJsonArray()) {
                dip2.slots = parseSlots(jsonObject.get("slots").getAsJsonArray());
            }
            else {
                dip2.slots = createEmptySlots();
            }
            dip2.minigameName = JsonUtils.getStringOr("minigameName", jsonObject, null);
            dip2.activeSlot = JsonUtils.getIntOr("activeSlot", jsonObject, -1);
            dip2.minigameId = JsonUtils.getIntOr("minigameId", jsonObject, -1);
            dip2.minigameImage = JsonUtils.getStringOr("minigameImage", jsonObject, null);
        }
        catch (Exception exception3) {
            RealmsServer.LOGGER.error("Could not parse McoServer: " + exception3.getMessage());
        }
        return dip2;
    }
    
    private static void sortInvited(final RealmsServer dip) {
        dip.players.sort((dim1, dim2) -> ComparisonChain.start().compareFalseFirst(dim2.getAccepted(), dim1.getAccepted()).compare(dim1.getName().toLowerCase(Locale.ROOT), dim2.getName().toLowerCase(Locale.ROOT)).result());
    }
    
    private static List<PlayerInfo> parseInvited(final JsonArray jsonArray) {
        final List<PlayerInfo> list2 = Lists.newArrayList();
        for (final JsonElement jsonElement4 : jsonArray) {
            try {
                final JsonObject jsonObject5 = jsonElement4.getAsJsonObject();
                final PlayerInfo dim6 = new PlayerInfo();
                dim6.setName(JsonUtils.getStringOr("name", jsonObject5, null));
                dim6.setUuid(JsonUtils.getStringOr("uuid", jsonObject5, null));
                dim6.setOperator(JsonUtils.getBooleanOr("operator", jsonObject5, false));
                dim6.setAccepted(JsonUtils.getBooleanOr("accepted", jsonObject5, false));
                dim6.setOnline(JsonUtils.getBooleanOr("online", jsonObject5, false));
                list2.add(dim6);
            }
            catch (Exception ex) {}
        }
        return list2;
    }
    
    private static Map<Integer, RealmsWorldOptions> parseSlots(final JsonArray jsonArray) {
        final Map<Integer, RealmsWorldOptions> map2 = Maps.newHashMap();
        for (final JsonElement jsonElement4 : jsonArray) {
            try {
                final JsonObject jsonObject6 = jsonElement4.getAsJsonObject();
                final JsonParser jsonParser7 = new JsonParser();
                final JsonElement jsonElement5 = jsonParser7.parse(jsonObject6.get("options").getAsString());
                RealmsWorldOptions div5;
                if (jsonElement5 == null) {
                    div5 = RealmsWorldOptions.createDefaults();
                }
                else {
                    div5 = RealmsWorldOptions.parse(jsonElement5.getAsJsonObject());
                }
                final int integer9 = JsonUtils.getIntOr("slotId", jsonObject6, -1);
                map2.put(integer9, div5);
            }
            catch (Exception ex) {}
        }
        for (int integer10 = 1; integer10 <= 3; ++integer10) {
            if (!map2.containsKey(integer10)) {
                map2.put(integer10, RealmsWorldOptions.createEmptyDefaults());
            }
        }
        return map2;
    }
    
    private static Map<Integer, RealmsWorldOptions> createEmptySlots() {
        final Map<Integer, RealmsWorldOptions> map1 = Maps.newHashMap();
        map1.put(1, RealmsWorldOptions.createEmptyDefaults());
        map1.put(2, RealmsWorldOptions.createEmptyDefaults());
        map1.put(3, RealmsWorldOptions.createEmptyDefaults());
        return map1;
    }
    
    public static RealmsServer parse(final String string) {
        try {
            return parse(new JsonParser().parse(string).getAsJsonObject());
        }
        catch (Exception exception2) {
            RealmsServer.LOGGER.error("Could not parse McoServer: " + exception2.getMessage());
            return new RealmsServer();
        }
    }
    
    private static State getState(final String string) {
        try {
            return State.valueOf(string);
        }
        catch (Exception exception2) {
            return State.CLOSED;
        }
    }
    
    private static WorldType getWorldType(final String string) {
        try {
            return WorldType.valueOf(string);
        }
        catch (Exception exception2) {
            return WorldType.NORMAL;
        }
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(this.id, this.name, this.motd, this.state, this.owner, this.expired);
    }
    
    @Override
    public boolean equals(final Object object) {
        if (object == null) {
            return false;
        }
        if (object == this) {
            return true;
        }
        if (object.getClass() != this.getClass()) {
            return false;
        }
        final RealmsServer dip3 = (RealmsServer)object;
        return new EqualsBuilder().append(this.id, dip3.id).append(this.name, dip3.name).append(this.motd, dip3.motd).append(this.state, dip3.state).append(this.owner, dip3.owner).append(this.expired, dip3.expired).append(this.worldType, this.worldType).isEquals();
    }
    
    public RealmsServer clone() {
        final RealmsServer dip2 = new RealmsServer();
        dip2.id = this.id;
        dip2.remoteSubscriptionId = this.remoteSubscriptionId;
        dip2.name = this.name;
        dip2.motd = this.motd;
        dip2.state = this.state;
        dip2.owner = this.owner;
        dip2.players = this.players;
        dip2.slots = this.cloneSlots(this.slots);
        dip2.expired = this.expired;
        dip2.expiredTrial = this.expiredTrial;
        dip2.daysLeft = this.daysLeft;
        dip2.serverPing = new RealmsServerPing();
        dip2.serverPing.nrOfPlayers = this.serverPing.nrOfPlayers;
        dip2.serverPing.playerList = this.serverPing.playerList;
        dip2.worldType = this.worldType;
        dip2.ownerUUID = this.ownerUUID;
        dip2.minigameName = this.minigameName;
        dip2.activeSlot = this.activeSlot;
        dip2.minigameId = this.minigameId;
        dip2.minigameImage = this.minigameImage;
        return dip2;
    }
    
    public Map<Integer, RealmsWorldOptions> cloneSlots(final Map<Integer, RealmsWorldOptions> map) {
        final Map<Integer, RealmsWorldOptions> map2 = Maps.newHashMap();
        for (final Map.Entry<Integer, RealmsWorldOptions> entry5 : map.entrySet()) {
            map2.put(entry5.getKey(), entry5.getValue().clone());
        }
        return map2;
    }
    
    public String getWorldName(final int integer) {
        return this.name + " (" + this.slots.get(integer).getSlotName(integer) + ")";
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
    
    public static class McoServerComparator implements Comparator<RealmsServer> {
        private final String refOwner;
        
        public McoServerComparator(final String string) {
            this.refOwner = string;
        }
        
        @Override
        public int compare(final RealmsServer dip1, final RealmsServer dip2) {
            return ComparisonChain.start().compareTrueFirst(dip1.state == State.UNINITIALIZED, dip2.state == State.UNINITIALIZED).compareTrueFirst(dip1.expiredTrial, dip2.expiredTrial).compareTrueFirst(dip1.owner.equals(this.refOwner), dip2.owner.equals(this.refOwner)).compareFalseFirst(dip1.expired, dip2.expired).compareTrueFirst(dip1.state == State.OPEN, dip2.state == State.OPEN).compare(dip1.id, dip2.id).result();
        }
    }
    
    public enum State {
        CLOSED, 
        OPEN, 
        UNINITIALIZED;
    }
    
    public enum WorldType {
        NORMAL, 
        MINIGAME, 
        ADVENTUREMAP, 
        EXPERIENCE, 
        INSPIRATION;
    }
}
