package controllers;

import akka.actor.ActorRef;
import akka.actor.Props;
import akka.pattern.Patterns;
import chesspresso.Chess;
import com.google.common.hash.Hashing;
import model.Input;
import play.cache.Cache;
import play.cache.Cached;
import play.data.DynamicForm;
import play.data.Form;
import play.libs.Akka;
import play.libs.ws.WS;
import play.libs.ws.WSResponse;
import util.ChessUtils;
import util.GifWriter;
import util.Lichess;
import play.libs.F;
import play.mvc.*;

import views.html.*;

import java.awt.image.BufferedImage;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import play.Logger;

import util.*;

import static play.libs.F.Promise.promise;

public class Application extends Controller {

  public Result index() {
    Form form = Form.form();
    return ok(index.render(form));
  }

  public Result about() {
    return ok(about.render());
  }

  public Result result(String key) {
    if (Cache.get(key) == null) {
      return notFound();
    }
    return ok(result.render(key));
  }

  public F.Promise<Result> gif(String key) {
    F.Promise<byte[]> result = (F.Promise<byte[]>) Cache.get(key);
    if (result != null) {
      return result.map(r -> ok(r).as("image/gif"));
    }

    return promise(() -> notFound());
  }

  public F.Promise<Result> download(String key) {
    F.Promise<byte[]> result = (F.Promise<byte[]>) Cache.get(key);
    if (result != null) {
      response().setHeader("Content-Disposition", "attachement");
      response().setHeader("filename", "chess-gif.gif");
      return result.map(r -> ok(r).as("image/gif"));
    }

    return promise(() -> notFound());
  }

  public F.Promise<Result> gfycat(String key) {
    F.Promise<WSResponse> responsePromise = WS.url("http://upload.gfycat.com/transcode?fetchUrl=" + controllers.routes.Application.gif(key).url()).get();
    return responsePromise.map(r -> r.asJson().get("gfyName").textValue())
      .map(name -> ok(gfycat.render(name)));
  }

  public F.Promise<Result> pgn() {
    DynamicForm requestData = Form.form().bindFromRequest();
    String pgn = requestData.get("pgn");
    String color = requestData.get("color");
    String sizeParam = requestData.get("size");
    int size = sizeParam != null ? Integer.valueOf(sizeParam) : 320;
    int plyStart = 0; //Integer.valueOf(requestData.get("plyStart"));
    int plyEnd = Integer.MAX_VALUE; //Integer.valueOf(requestData.get("plyEnd"));

    String key = Hashing.murmur3_32().hashUnencodedChars(pgn + "-" + color + "-" + size + "-" + plyStart + "-" + plyEnd).toString();

    F.Promise<byte[]> result = Cache.getOrElse(key, new Callable<F.Promise<byte[]>>() {
      @Override public F.Promise<byte[]> call() throws Exception {
        return promise(() -> ChessUtils.gif(pgn, color, size, plyStart, plyEnd));
      }
    }, 0);

    return result.map((r) -> temporaryRedirect(controllers.routes.Application.result(key)));
  }
}

@@ -120,24 +120,72 @@
 esso.Chess;%0A
+import com.fasterxml.jackson.databind.JsonNode;%0A
 import com.g
@@ -1843,55 +1843,21 @@
     
-F.Promise%3CWSResponse%3E responsePromise = WS.url(
+String url = 
 %22htt
@@ -1901,28 +1901,16 @@
 Url=%22 + 
-controllers.
 routes.A
@@ -1938,52 +1938,249 @@
 rl()
-).get();%0A    return responsePromise.map(r -%3E
+;%0A%0A    Logger.debug(%22Gfycatting a gif: %22 + url);%0A    F.Promise%3CWSResponse%3E responsePromise = WS.url(url).get();%0A    return responsePromise.map(r -%3E %7B%0A      Logger.debug(%22Gfycatting a gif: response = %22 + r.getBody());%0A      JsonNode gfyName =
  r.a
@@ -2201,16 +2201,38 @@
 fyName%22)
+;%0A      return gfyName
 .textVal
@@ -2235,16 +2235,23 @@
 tValue()
+;%0A    %7D
 )%0A      

Debug gfycat