package net.glowstone.io;

import net.glowstone.GlowServer;
import net.glowstone.entity.GlowPlayer;
import net.glowstone.util.StatisticMap;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.UUID;

public class PlayerStatisticIoService {

    private GlowServer server;
    private File statsDir;

    public PlayerStatisticIoService(GlowServer server, File statsDir) {
        this.server = server;
        this.statsDir = statsDir;
    }

    /**
     * Gets the statistics file for the given UUID
     *
     * @param uuid the UUID of the player
     * @return the statistics file of the given UUID
     */
    private File getPlayerFile(UUID uuid) {
        if (!statsDir.isDirectory() && !statsDir.mkdirs()) {
            server.getLogger().warning("Failed to create directory: " + statsDir);
        }
        return new File(statsDir, uuid + ".json");
    }

    /**
     * Reads the stats of a player from its statistics file and writes the values to the StatisticMap.
     *
     * @param player the player to read the statistics from
     */
    public void readStats(GlowPlayer player) {
        File statsFile = getPlayerFile(player.getUniqueId());
        player.getStatisticMap().getValues().clear();
        if (statsFile.exists()) {
            try {
                JSONParser parser = new JSONParser();
                JSONObject json = (JSONObject) parser.parse(new FileReader(statsFile));
                for (Object o : json.keySet()) {
                    String key = (String) o;
                    Long longValue = null;
                    try {
                        longValue = ((Long) json.get(o));
                    } catch (ClassCastException e) {
                        GlowServer.logger.info("Unknown statistic: (" + key + ", " + json.get(o) + ")");
                    }
                    if (longValue != null) {
                        player.getStatisticMap().getValues().put(key, longValue.intValue());
                    }
                }
            } catch (ParseException | IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Writes the statistics of the player into its statistics file.
     *
     * @param player the player to write the statistics file from
     */
    public void writeStats(GlowPlayer player) {
        File file = getPlayerFile(player.getUniqueId());
        StatisticMap map = player.getStatisticMap();
        JSONObject json = new JSONObject(map.getValues());
        try {
            FileWriter writer = new FileWriter(file, false);
            writer.write(json.toJSONString());
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

@@ -1744,35 +1744,64 @@
                 
-try
+if (json.get(o) instanceof Long)
  %7B%0A             
@@ -1823,17 +1823,16 @@
 Value = 
-(
 (Long) j
@@ -1841,17 +1841,16 @@
 n.get(o)
-)
 ;%0A      
@@ -1869,36 +1869,303 @@
   %7D 
-catch (ClassCastException e)
+else if (json.get(o) instanceof JSONObject) %7B%0A                        JSONObject object = (JSONObject) json.get(o);%0A                        if (object.containsKey(%22value%22)) %7B%0A                            longValue = (Long) object.get(%22value%22);%0A                        %7D%0A                    %7D else
  %7B%0A 
@@ -2209,12 +2209,15 @@
 ger.
-info
+warning
 (%22Un
@@ -2235,38 +2235,95 @@
 stic
-: (%22 + key + %22, %22 + json.get(o
+ type for '%22 + key + %22': %22 + json.get(o) + %22 (%22 + json.get(o).getClass().getSimpleName(
 ) + 

Allow for progress-based achievements to be loaded. Fixes #349