/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package runtime.actionContainers

import org.junit.runner.RunWith
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import spray.json.DefaultJsonProtocol._
import spray.json._

import ActionContainer.withContainer
import ResourceHelpers.JarBuilder

import common.WskActorSystem

@RunWith(classOf[JUnitRunner])
class JavaActionContainerTests extends FlatSpec with Matchers with WskActorSystem with ActionProxyContainerTestUtils {

  // Helpers specific to java actions
  def withJavaContainer(code: ActionContainer => Unit, env: Map[String, String] = Map.empty) =
    withContainer("java8action", env)(code)

  override def initPayload(mainClass: String, jar64: String) =
    JsObject(
      "value" -> JsObject("name" -> JsString("dummyAction"), "main" -> JsString(mainClass), "code" -> JsString(jar64)))

  behavior of "Java action"

  it should s"run a java snippet and confirm expected environment variables" in {
    val props = Seq(
      "api_host" -> "xyz",
      "api_key" -> "abc",
      "namespace" -> "zzz",
      "action_name" -> "xxx",
      "activation_id" -> "iii",
      "deadline" -> "123")
    val env = props.map { case (k, v) => s"__OW_${k.toUpperCase}" -> v }
    val (out, err) =
      withJavaContainer(
        { c =>
          val jar = JarBuilder.mkBase64Jar(
            Seq("example", "HelloWhisk.java") -> """
                    | package example;
                    |
                    | import com.google.gson.JsonObject;
                    |
                    | public class HelloWhisk {
                    |     public static JsonObject main(JsonObject args) {
                    |         JsonObject response = new JsonObject();
                    |         response.addProperty("api_host", System.getenv("__OW_API_HOST"));
                    |         response.addProperty("api_key", System.getenv("__OW_API_KEY"));
                    |         response.addProperty("namespace", System.getenv("__OW_NAMESPACE"));
                    |         response.addProperty("action_name", System.getenv("__OW_ACTION_NAME"));
                    |         response.addProperty("activation_id", System.getenv("__OW_ACTIVATION_ID"));
                    |         response.addProperty("deadline", System.getenv("__OW_DEADLINE"));
                    |         return response;
                    |     }
                    | }
                """.stripMargin.trim)

          val (initCode, _) = c.init(initPayload("example.HelloWhisk", jar))
          initCode should be(200)

          val (runCode, out) = c.run(runPayload(JsObject(), Some(props.toMap.toJson.asJsObject)))
          runCode should be(200)
          props.map {
            case (k, v) => out.get.fields(k) shouldBe JsString(v)

          }
        },
        env.take(1).toMap)

    out.trim shouldBe empty
    err.trim shouldBe empty
  }

  it should "support valid flows" in {
    val (out, err) = withJavaContainer { c =>
      val jar = JarBuilder.mkBase64Jar(
        Seq("example", "HelloWhisk.java") -> """
                    | package example;
                    |
                    | import com.google.gson.JsonObject;
                    |
                    | public class HelloWhisk {
                    |     public static JsonObject main(JsonObject args) {
                    |         String name = args.getAsJsonPrimitive("name").getAsString();
                    |         JsonObject response = new JsonObject();
                    |         response.addProperty("greeting", "Hello " + name + "!");
                    |         return response;
                    |     }
                    | }
                """.stripMargin.trim)

      val (initCode, _) = c.init(initPayload("example.HelloWhisk", jar))
      initCode should be(200)

      val (runCode1, out1) = c.run(runPayload(JsObject("name" -> JsString("Whisk"))))
      runCode1 should be(200)
      out1 should be(Some(JsObject("greeting" -> JsString("Hello Whisk!"))))

      val (runCode2, out2) = c.run(runPayload(JsObject("name" -> JsString("ksihW"))))
      runCode2 should be(200)
      out2 should be(Some(JsObject("greeting" -> JsString("Hello ksihW!"))))
    }

    out.trim shouldBe empty
    err.trim shouldBe empty
  }

  it should "handle unicode in source, input params, logs, and result" in {
    val (out, err) = withJavaContainer { c =>
      val jar = JarBuilder.mkBase64Jar(
        Seq("example", "HelloWhisk.java") -> """
                    | package example;
                    |
                    | import com.google.gson.JsonObject;
                    |
                    | public class HelloWhisk {
                    |     public static JsonObject main(JsonObject args) {
                    |         String delimiter = args.getAsJsonPrimitive("delimiter").getAsString();
                    |         JsonObject response = new JsonObject();
                    |          String str = delimiter + " ☃ " + delimiter;
                    |          System.out.println(str);
                    |          response.addProperty("winter", str);
                    |          return response;
                    |     }
                    | }
            """.stripMargin)

      val (initCode, _) = c.init(initPayload("example.HelloWhisk", jar))
      val (runCode, runRes) = c.run(runPayload(JsObject("delimiter" -> JsString("❄"))))
      runRes.get.fields.get("winter") shouldBe Some(JsString("❄ ☃ ❄"))
    }

    out should include("❄ ☃ ❄")
    err.trim shouldBe empty
  }

  it should "fail to initialize with bad code" in {
    val (out, err) = withJavaContainer { c =>
      // This is valid zip file containing a single file, but not a valid
      // jar file.
      val brokenJar = ("UEsDBAoAAAAAAPxYbkhT4iFbCgAAAAoAAAANABwAbm90YWNsYXNzZmlsZVV" +
        "UCQADzNPmVszT5lZ1eAsAAQT1AQAABAAAAABzYXVjaXNzb24KUEsBAh4DCg" +
        "AAAAAA/FhuSFPiIVsKAAAACgAAAA0AGAAAAAAAAQAAAKSBAAAAAG5vdGFjb" +
        "GFzc2ZpbGVVVAUAA8zT5lZ1eAsAAQT1AQAABAAAAABQSwUGAAAAAAEAAQBT" +
        "AAAAUQAAAAAA")

      val (initCode, _) = c.init(initPayload("example.Broken", brokenJar))
      initCode should not be (200)
    }

    // Somewhere, the logs should contain an exception.
    val combined = out + err
    combined.toLowerCase should include("exception")
  }

  it should "return some error on action error" in {
    val (out, err) = withJavaContainer { c =>
      val jar = JarBuilder.mkBase64Jar(
        Seq("example", "HelloWhisk.java") -> """
                    | package example;
                    |
                    | import com.google.gson.JsonObject;
                    |
                    | public class HelloWhisk {
                    |     public static JsonObject main(JsonObject args) throws Exception {
                    |         throw new Exception("noooooooo");
                    |     }
                    | }
                """.stripMargin.trim)

      val (initCode, _) = c.init(initPayload("example.HelloWhisk", jar))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runCode should not be (200)

      runRes shouldBe defined
      runRes.get.fields.get("error") shouldBe defined
    }

    val combined = out + err
    combined.toLowerCase should include("exception")
  }

  it should "support application errors" in {
    val (out, err) = withJavaContainer { c =>
      val jar = JarBuilder.mkBase64Jar(
        Seq("example", "Error.java") -> """
                    | package example;
                    |
                    | import com.google.gson.JsonObject;
                    |
                    | public class Error {
                    |     public static JsonObject main(JsonObject args) throws Exception {
                    |         JsonObject error = new JsonObject();
                    |         error.addProperty("error", "This action is unhappy.");
                    |         return error;
                    |     }
                    | }
                """.stripMargin.trim)

      val (initCode, _) = c.init(initPayload("example.Error", jar))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runCode should be(200) // action writer returning an error is OK

      runRes shouldBe defined
      runRes.get.fields.get("error") shouldBe defined
    }

    val combined = out + err
    combined.trim shouldBe empty
  }

  it should "survive System.exit" in {
    val (out, err) = withJavaContainer { c =>
      val jar =
        JarBuilder.mkBase64Jar(Seq("example", "Quitter.java") -> """
                    | package example;
                    |
                    | import com.google.gson.*;
                    |
                    | public class Quitter {
                    |     public static JsonObject main(JsonObject main) {
                    |         System.exit(1);
                    |         return new JsonObject();
                    |     }
                    | }
                """.stripMargin.trim)

      val (initCode, _) = c.init(initPayload("example.Quitter", jar))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runCode should not be (200)

      runRes shouldBe defined
      runRes.get.fields.get("error") shouldBe defined
    }

    val combined = out + err
    combined.toLowerCase should include("system.exit")
  }

  it should "enforce that the user returns an object" in {
    withJavaContainer { c =>
      val jar =
        JarBuilder.mkBase64Jar(Seq("example", "Nuller.java") -> """
                    | package example;
                    |
                    | import com.google.gson.*;
                    |
                    | public class Nuller {
                    |     public static JsonObject main(JsonObject args) {
                    |         return null;
                    |     }
                    | }
                """.stripMargin.trim)

      val (initCode, _) = c.init(initPayload("example.Nuller", jar))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runCode should not be (200)

      runRes shouldBe defined
      runRes.get.fields.get("error") shouldBe defined
    }
  }

  val dynamicLoadingJar = JarBuilder.mkBase64Jar(
    Seq(
      Seq("example", "EntryPoint.java") -> """
                | package example;
                |
                | import com.google.gson.*;
                | import java.lang.reflect.*;
                |
                | public class EntryPoint {
                |     private final static String CLASS_NAME = "example.DynamicClass";
                |     public static JsonObject main(JsonObject args) throws Exception {
                |         String cl = args.getAsJsonPrimitive("classLoader").getAsString();
                |
                |         Class d = null;
                |         if("local".equals(cl)) {
                |             d = Class.forName(CLASS_NAME);
                |         } else if("thread".equals(cl)) {
                |             d = Thread.currentThread().getContextClassLoader().loadClass(CLASS_NAME);
                |         }
                |
                |         Object o = d.newInstance();
                |         Method m = o.getClass().getMethod("getMessage");
                |         String msg = (String)m.invoke(o);
                |
                |         JsonObject response = new JsonObject();
                |         response.addProperty("message", msg);
                |         return response;
                |     }
                | }
                |""".stripMargin.trim,
      Seq("example", "DynamicClass.java") -> """
                | package example;
                |
                | public class DynamicClass {
                |     public String getMessage() {
                |         return "dynamic!";
                |     }
                | }
                |""".stripMargin.trim))

  def classLoaderTest(param: String) = {
    val (out, err) = withJavaContainer { c =>
      val (initCode, _) = c.init(initPayload("example.EntryPoint", dynamicLoadingJar))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject("classLoader" -> JsString(param))))
      runCode should be(200)

      runRes shouldBe defined
      runRes.get.fields.get("message") shouldBe Some(JsString("dynamic!"))
    }
    (out ++ err).trim shouldBe empty
  }

  it should "support loading classes from the current classloader" in {
    classLoaderTest("local")
  }

  it should "support loading classes from the Thread classloader" in {
    classLoaderTest("thread")
  }
}
