package com.nincraft.modpackdownloader;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import com.nincraft.modpackdownloader.util.Reference;

public class ModUpdater {

	static Logger logger = LogManager.getRootLogger();

	private static final String[] formats = { "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss'Z'",
			"yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
			"yyyy-MM-dd HH:mm:ss", "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy'T'HH:mm:ss.SSS'Z'", "MM/dd/yyyy'T'HH:mm:ss.SSSZ",
			"MM/dd/yyyy'T'HH:mm:ss.SSS", "MM/dd/yyyy'T'HH:mm:ssZ", "MM/dd/yyyy'T'HH:mm:ss", "yyyy:MM:dd HH:mm:ss", };

	public static void updateCurseMods(String manifestFile, String mcVersion, String releaseType) {
		try {
			Long projectID;
			Long fileID;
			JSONParser parser = new JSONParser();
			JSONObject jsons = (JSONObject) parser.parse(new FileReader(manifestFile));
			JSONArray fileList = (JSONArray) jsons.get("curseFiles");
			if (fileList == null) {
				fileList = (JSONArray) jsons.get("files");
			}
			if (fileList != null) {
				Iterator iterator = fileList.iterator();
				while (iterator.hasNext()) {
					JSONObject modJson = (JSONObject) iterator.next();
					projectID = (Long) modJson.get("projectID");
					fileID = (Long) modJson.get("fileID");
					String url = Reference.CURSEFORGE_BASE_URL + projectID + Reference.COOKIE_TEST_1;
					HttpURLConnection con = (HttpURLConnection) (new URL(url).openConnection());
					con.setInstanceFollowRedirects(false);
					con.connect();
					String location = con.getHeaderField("Location");
					String projectName = location.split("/")[2];
					JSONParser projectParser = new JSONParser();
					JSONObject projectJson = getCurseProjectJson(projectID, projectName, projectParser);
					JSONObject fileListJson = (JSONObject) projectJson.get("files");
					Date lastDate = null;
					Long mostRecent = fileID;
					for (Object thing : fileListJson.keySet()) {
						JSONObject file = (JSONObject) fileListJson.get(thing);
						Date date = parseDate((String) file.get("created_at"));
						if (lastDate == null) {
							lastDate = date;
						}
						if (lastDate.before(date) && file.get("type").equals(releaseType)
								&& file.get("version").equals(mcVersion)) {
							mostRecent = (Long) file.get("id");
							lastDate = date;
						}
					}
					if (!mostRecent.equals(fileID)) {
						logger.info("Most recent version of " + projectName + " is " + mostRecent + ". Old version was "
								+ fileID);
						modJson.remove("fileID");
						modJson.put("fileID", mostRecent);
					}
				}
			}
			FileWriter file = new FileWriter(manifestFile);
			try {
				file.write(jsons.toJSONString());
			} finally {
				file.flush();
				file.close();
			}

		} catch (FileNotFoundException e) {
			logger.error(e.getMessage());
		} catch (IOException e) {
			logger.error(e.getMessage());
		} catch (ParseException e) {
			logger.error(e.getMessage());
		}
	}

	private static JSONObject getCurseProjectJson(Long projectID, String projectName, JSONParser projectParser)
			throws ParseException, IOException {
		try {
			return (JSONObject) projectParser.parse(new BufferedReader(new InputStreamReader(
					new URL("http://widget.mcf.li/mc-mods/minecraft/" + projectName + ".json").openStream())));
		} catch (FileNotFoundException e) {
			return (JSONObject) projectParser.parse(new BufferedReader(new InputStreamReader(
					new URL("http://widget.mcf.li/mc-mods/minecraft/" + projectID + "-" + projectName + ".json")
							.openStream())));
		}
	}

	private static Date parseDate(String date) {
		Date d = null;
		if (date != null) {
			for (String parse : formats) {
				SimpleDateFormat sdf = new SimpleDateFormat(parse);
				try {
					d = sdf.parse(date);
				} catch (java.text.ParseException e) {

				}
			}
		}
		return d;
	}

}

@@ -2407,16 +2407,83 @@
 fileID;%0A
+%09%09%09%09%09String mostRecentFile = null;%0A%09%09%09%09%09String currentFile = null;%0A
 %09%09%09%09%09for
@@ -2880,39 +2880,194 @@
 d%22);%0A%09%09%09%09%09%09%09
-lastDate = date
+mostRecentFile = (String) file.get(%22name%22);%0A%09%09%09%09%09%09%09lastDate = date;%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09if(fileID.equals((Long) file.get(%22id%22)))%7B%0A%09%09%09%09%09%09%09currentFile = (String) file.get(%22name%22)
 ;%0A%09%09%09%09%09%09%7D%0A%09%09
@@ -3189,16 +3189,20 @@
 stRecent
+File
  + %22. Ol
@@ -3231,17 +3231,23 @@
 %09%09+ 
-f
+currentF
 ile
-ID
 );%0A
+%0A
 %09%09%09%09
@@ -3318,24 +3318,92 @@
 nt);%0A%09%09%09%09%09%7D%0A
+%09%09%09%09%09modJson.remove(%22name%22);%0A%09%09%09%09%09modJson.put(%22name%22, projectName);%0A
 %09%09%09%09%7D%0A%09%09%09%7D%0A%09

Fix some logging to display new and old file when updating