/*
 * 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 actionContainers

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import common.WskActorSystem
import spray.json.DefaultJsonProtocol._
import spray.json._
import actionContainers.ResourceHelpers.JarBuilder
import actionContainers.ActionContainer.withContainer
import org.scalatest.Matchers

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

  val image = "java8action"
  val errPrefix = "\"An error has occurred (see logs for details):"
  val checkStreamsAtInit = true
  // this is true for the Java based runtime but not for actionloop
  // since it does not parse the output and the invoker change the status anyway
  val runtimeDetectErrors = true

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

  behavior of "Java action"

  override val testNoSourceOrExec = {
    TestConfig("")
  }

  override val testNotReturningJson = {
    // skip this test since and add own below (see Nuller)
    TestConfig("", skipTest = true)
  }

  override val testEnv = {
    TestConfig(
      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("action_version", System.getenv("__OW_ACTION_VERSION"));
            |         response.addProperty("activation_id", System.getenv("__OW_ACTIVATION_ID"));
            |         response.addProperty("deadline", System.getenv("__OW_DEADLINE"));
            |         return response;
            |     }
            | }
          """.stripMargin.trim),
      main = "example.HelloWhisk")
  }

  override val testEcho = {
    TestConfig(
      JarBuilder.mkBase64Jar(
        Seq("example", "HelloWhisk.java") ->
          """
            | package example;
            |
            | import com.google.gson.JsonObject;
            |
            | public class HelloWhisk {
            |     public static JsonObject main(JsonObject args) {
            |         System.out.println("hello stdout");
            |         System.err.println("hello stderr");
            |         return args;
            |     }
            | }
          """.stripMargin.trim),
      "example.HelloWhisk")

  }

  override val testUnicode = {
    TestConfig(
      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),
      "example.HelloWhisk")
  }

  def echo(main: String = "main") = {
    JarBuilder.mkBase64Jar(
      Seq("example", "HelloWhisk.java") ->
        s"""
           | package example;
           |
        | import com.google.gson.JsonObject;
           |
        | public class HelloWhisk {
           |     public static JsonObject $main(JsonObject args) {
           |         return args;
           |     }
           | }
      """.stripMargin.trim)
  }

  override val testInitCannotBeCalledMoreThanOnce = {
    TestConfig(echo(), "example.HelloWhisk")
  }

  override val testEntryPointOtherThanMain = {
    TestConfig(echo("naim"), "example.HelloWhisk#naim")
  }

  override val testLargeInput = {
    TestConfig(echo(), "example.HelloWhisk")
  }

  Seq("", "x", "!", "#", "#main", "#bogus").foreach { m =>
    it should s"report an error if explicit 'main' is not found ($m)" in {
      val (out, err) = withActionContainer() { c =>
        val (initCode, out) = c.init(initPayload(echo("hello"), s"example.HelloWhisk$m"))
        initCode shouldBe 502

        val expected = m match {
          case c if c == "x" || c == "!" => s"$errPrefix java.lang.ClassNotFoundException: example.HelloWhisk$c"
          case "#bogus" =>
            s"$errPrefix java.lang.NoSuchMethodException: example.HelloWhisk.bogus(com.google.gson.JsonObject)"
          case _ => s"$errPrefix java.lang.NoSuchMethodException: example.HelloWhisk.main(com.google.gson.JsonObject)"
        }

        val error = out.get.fields.get("error").get.toString()

        println(error)
        println(expected)

        error should startWith(expected)
      }

      if (checkStreamsAtInit)
        checkStreams(out, err, {
          case (o, e) =>
            o shouldBe empty
            e should not be empty
        })
    }
  }

  it should "fail to initialize with bad code" in {
    val (out, err) = withActionContainer() { 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(brokenJar, "example.Broken"))
      initCode should not be (200)
    }

    // Somewhere, the logs should contain an exception.
    if (checkStreamsAtInit)
      checkStreams(out, err, {
        case (o, e) =>
          (o + e).toLowerCase should include("exception")
      })
  }

  it should "return some error on action error" in {
    val (out, err) = withActionContainer() { 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(jar, "example.HelloWhisk"))
      initCode should be(200)

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

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

    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("exception")
    })
  }

  it should "support application errors" in {
    val (out, err) = withActionContainer() { 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(jar, "example.Error"))
      initCode should be(200)

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

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

    checkStreams(out, err, {
      case (o, e) =>
        o shouldBe empty
        e shouldBe empty
    })
  }

  it should "support main in default package" in {
    val (out, err) = withActionContainer() { c =>
      val jar = JarBuilder.mkBase64Jar(
        Seq("", "HelloWhisk.java") ->
          """
            | import com.google.gson.JsonObject;
            |
            | public class HelloWhisk {
            |     public static JsonObject main(JsonObject args) throws Exception {
            |         return args;
            |     }
            | }
          """.stripMargin.trim)

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

      val args = JsObject("a" -> "A".toJson)
      val (runCode, runRes) = c.run(runPayload(args))
      runCode should be(200)
      runRes shouldBe Some(args)
    }

    checkStreams(out, err, {
      case (o, e) =>
        o shouldBe empty
        e shouldBe empty
    })
  }

  it should "survive System.exit" in {
    val (out, err) = withActionContainer() { 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(jar, "example.Quitter"))
      initCode should be(200)

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

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

    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("system.exit")
    })
  }

  it should "enforce that the user returns an object" in {
    val (out, err) = withActionContainer() { 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(jar, "example.Nuller"))
      initCode should be(200)

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

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

    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("the action returned null")
    })
  }

  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) = withActionContainer() { c =>
      val (initCode, _) = c.init(initPayload(dynamicLoadingJar, "example.EntryPoint"))
      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!"))
    }

    checkStreams(out, err, {
      case (o, e) =>
        o shouldBe empty
        e 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")
  }
}
