package com.faforever.client.remote;

import com.faforever.client.fx.JavaFxUtil;
import com.faforever.client.preferences.PreferencesService;
import javafx.scene.image.Image;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.validator.routines.UrlValidator;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;

import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Supplier;

import static com.github.nocatch.NoCatch.noCatch;


@Lazy
@Service
@Slf4j
public class AssetService {

  private final PreferencesService preferencesService;
  private final UrlValidator urlValidator;

  public AssetService(PreferencesService preferencesService) {
    this.preferencesService = preferencesService;
    urlValidator = new UrlValidator();
  }

  @Nullable
  public Image loadAndCacheImage(URL url, Path cacheSubFolder, @Nullable Supplier<Image> defaultSupplier) {
    return loadAndCacheImage(url, cacheSubFolder, defaultSupplier, 0, 0);
  }

  @Nullable
  public Image loadAndCacheImage(URL url, Path cacheSubFolder, @Nullable Supplier<Image> defaultSupplier, int width, int height) {
    if (url == null) {
      if (defaultSupplier == null) {
        return null;
      }
      return defaultSupplier.get();
    }

    String urlString = url.toString();
    urlString = urlValidator.isValid(urlString) ? urlString : UriUtils.encodePath(urlString, StandardCharsets.UTF_8);
    String filename = urlString.substring(urlString.lastIndexOf('/') + 1);
    Path cachePath = preferencesService.getCacheDirectory().resolve(cacheSubFolder).resolve(filename);
    if (Files.exists(cachePath)) {
      log.debug("Using cached image: {}", cachePath);
      return new Image(noCatch(() -> cachePath.toUri().toURL().toExternalForm()), width, height, true, true);
    }

    log.debug("Fetching image {}", url);
    Image image = new Image(urlString, width, height, true, true, true);
    JavaFxUtil.persistImage(image, cachePath, filename.substring(filename.lastIndexOf('.') + 1));
    return image;
  }
}

@@ -540,16 +540,59 @@
 .Files;%0A
+import java.nio.file.InvalidPathException;%0A
 import j
@@ -1476,24 +1476,36 @@
 t();%0A    %7D%0A%0A
+    try %7B%0A  
     String u
@@ -1527,24 +1527,26 @@
 toString();%0A
+  
     urlStrin
@@ -1651,16 +1651,18 @@
 UTF_8);%0A
+  
     Stri
@@ -1732,16 +1732,18 @@
 1);%0A    
+  
 Path cac
@@ -1833,24 +1833,26 @@
 ename);%0A    
+  
 if (Files.ex
@@ -1866,24 +1866,26 @@
 chePath)) %7B%0A
+  
       log.de
@@ -1926,16 +1926,18 @@
 ePath);%0A
+  
       re
@@ -2038,27 +2038,31 @@
  true);%0A    
+  
 %7D%0A%0A
+  
     log.debu
@@ -2090,16 +2090,18 @@
 , url);%0A
+  
     Imag
@@ -2161,24 +2161,26 @@
 rue, true);%0A
+  
     JavaFxUt
@@ -2265,24 +2265,26 @@
  + 1));%0A    
+  
 return image
@@ -2285,14 +2285,236 @@
  image;%0A
+    %7D catch (InvalidPathException e) %7B%0A      log.warn(%22Unable to load image due to invalid fileName %7B%7D%22, url, e);%0A      if (defaultSupplier == null) %7B%0A        return null;%0A      %7D%0A      return defaultSupplier.get();%0A    %7D%0A
   %7D%0A%7D%0A

add catch for invalid file name (#2262)