From ad79cb3b21f086849bd4449a148ee8df93568dd3 Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Fri, 9 Aug 2019 16:31:29 +0100
Subject: [PATCH] Very fun indeed

---
 .../infra/packwiz/installer/DownloadTask.java | 68 ++++++++++++-------
 .../packwiz/installer/UpdateManager.java      |  4 +-
 .../installer/metadata/ManifestFile.java      | 10 +--
 3 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/src/main/java/link/infra/packwiz/installer/DownloadTask.java b/src/main/java/link/infra/packwiz/installer/DownloadTask.java
index 13ea4ee..80c8411 100644
--- a/src/main/java/link/infra/packwiz/installer/DownloadTask.java
+++ b/src/main/java/link/infra/packwiz/installer/DownloadTask.java
@@ -12,25 +12,19 @@ import java.util.List;
 
 class DownloadTask implements IOptionDetails {
 	final IndexFile.File metadata;
+	ManifestFile.File cachedFile = null;
 	private Exception failure = null;
-	private boolean complete = false;
+	private boolean alreadyUpToDate = false;
+	private boolean metadataRequired = true;
 	private boolean invalidated = false;
-	private boolean optionValue = true;
 	// If file is new or isOptional changed to true, the option needs to be presented again
 	private boolean newOptional = true;
 
 	public DownloadTask(IndexFile.File metadata) {
 		this.metadata = metadata;
-		if (this.metadata.linkedFile != null) {
-			if (this.metadata.linkedFile.option != null) {
-				// Set option to it's default value
-				optionValue = this.metadata.linkedFile.option.defaultValue;
-			}
-		}
 	}
 
 	public void setDefaultHashFormat(String format) {
-		if (failure != null || complete) return;
 		if (metadata.hashFormat == null || metadata.hashFormat.length() == 0) {
 			metadata.hashFormat = format;
 		}
@@ -38,13 +32,15 @@ class DownloadTask implements IOptionDetails {
 
 	public void invalidate() {
 		invalidated = true;
-		complete = false;
+		alreadyUpToDate = false;
 	}
 
 	public void updateFromCache(ManifestFile.File cachedFile) {
-		if (failure != null || complete) return;
+		if (failure != null) return;
 		if (cachedFile == null) return;
 
+		this.cachedFile = cachedFile;
+
 		if (!invalidated) {
 			Hash currHash = null;
 			try {
@@ -55,25 +51,41 @@ class DownloadTask implements IOptionDetails {
 			}
 			if (currHash != null && currHash.equals(cachedFile.hash)) {
 				// Already up to date
-				complete = true;
+				alreadyUpToDate = true;
+				metadataRequired = false;
 			}
 		}
 		if (cachedFile.isOptional) {
-			// Set option to the cached value
-			optionValue = cachedFile.optionValue;
-			if (isOptional()) {
-				// isOptional didn't change
-				newOptional = false;
-			}
+			// Because option selection dialog might set this task to true/false, metadata is always needed to download
+			// the file, and to show the description and name
+			metadataRequired = true;
 		}
 	}
 
 	public void downloadMetadata(IndexFile parentIndexFile, URI indexUri) {
-		if (failure != null || complete) return;
-		try {
-			metadata.downloadMeta(parentIndexFile, indexUri);
-		} catch (Exception e) {
-			failure = e;
+		if (failure != null) return;
+		if (metadataRequired) {
+			try {
+				metadata.downloadMeta(parentIndexFile, indexUri);
+			} catch (Exception e) {
+				failure = e;
+				return;
+			}
+			if (metadata.linkedFile != null) {
+				if (metadata.linkedFile.option != null) {
+					if (metadata.linkedFile.option.optional) {
+						if (cachedFile.isOptional) {
+							// isOptional didn't change
+							newOptional = false;
+						} else {
+							// isOptional false -> true, set option to it's default value
+							// TODO: preserve previous option value, somehow??
+							cachedFile.optionValue = this.metadata.linkedFile.option.defaultValue;
+						}
+					}
+				}
+				cachedFile.isOptional = isOptional();
+			}
 		}
 	}
 
@@ -98,7 +110,7 @@ class DownloadTask implements IOptionDetails {
 
 	@Override
 	public boolean getOptionValue() {
-		return this.optionValue;
+		return this.cachedFile.optionValue;
 	}
 
 	@Override
@@ -110,8 +122,12 @@ class DownloadTask implements IOptionDetails {
 	}
 
 	public void setOptionValue(boolean value) {
-		// TODO: if this is false, ensure the file is deleted in the actual download stage
-		this.optionValue = value;
+		// TODO: if this is false, ensure the file is deleted in the actual download stage (regardless of alreadyUpToDate?)
+		if (value && !this.cachedFile.optionValue) {
+			// Ensure that an update is done if it changes from false to true
+			alreadyUpToDate = false;
+		}
+		this.cachedFile.optionValue = value;
 	}
 
 	public static List<DownloadTask> createTasksFromIndex(IndexFile index) {
diff --git a/src/main/java/link/infra/packwiz/installer/UpdateManager.java b/src/main/java/link/infra/packwiz/installer/UpdateManager.java
index 0e89fdc..48e81e8 100644
--- a/src/main/java/link/infra/packwiz/installer/UpdateManager.java
+++ b/src/main/java/link/infra/packwiz/installer/UpdateManager.java
@@ -276,9 +276,9 @@ public class UpdateManager {
 		List<DownloadTask> failedTasks = tasks.stream().filter(t -> t.getException() != null).collect(Collectors.toList());
 
 		// If options changed, present all options again
-		if (tasks.stream().filter(DownloadTask::isNewOptional).count() > 0) {
+		if (tasks.stream().anyMatch(DownloadTask::isNewOptional)) {
 			List<IOptionDetails> opts = tasks.stream().filter(DownloadTask::isOptional).collect(Collectors.toList());
-			// TODO: present options
+			ui.showOptions(opts);
 		}
 
 		// TODO: different thread pool type?
diff --git a/src/main/java/link/infra/packwiz/installer/metadata/ManifestFile.java b/src/main/java/link/infra/packwiz/installer/metadata/ManifestFile.java
index 1107d03..f11d18f 100644
--- a/src/main/java/link/infra/packwiz/installer/metadata/ManifestFile.java
+++ b/src/main/java/link/infra/packwiz/installer/metadata/ManifestFile.java
@@ -1,21 +1,21 @@
 package link.infra.packwiz.installer.metadata;
 
+import link.infra.packwiz.installer.metadata.hash.Hash;
+
 import java.net.URI;
 import java.util.Map;
 
-import link.infra.packwiz.installer.metadata.hash.Hash;
-
 public class ManifestFile {
-	
 	public Hash packFileHash = null;
 	public Hash indexFileHash = null;
 	public Map<URI, File> cachedFiles;
 
 	public static class File {
 		public Hash hash = null;
-		public boolean isOptional = false;
-		public boolean optionValue = true;
 		public Hash linkedFileHash = null;
 		public String cachedLocation = null;
+
+		public boolean isOptional = false;
+		public boolean optionValue = true;
 	}
 }
\ No newline at end of file