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