/*
 * 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("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")
  }
}
