/*
 * 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 java.io.File
import java.util.Base64

import org.apache.commons.io.FileUtils
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

import ActionContainer.withContainer
import common.TestUtils
import common.WskActorSystem
import spray.json.DefaultJsonProtocol._
import spray.json._

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

    override def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit) = {
        withContainer("dockerskeleton", env)(code)
    }

    val codeNotReturningJson = """
           |#!/bin/sh
           |echo not a json object
        """.stripMargin.trim

    /** Standard code samples, should print 'hello' to stdout and echo the input args. */
    val stdCodeSamples = {
        val bash = """
                |#!/bin/bash
                |echo 'hello stdout'
                |echo 'hello stderr' 1>&2
                |if [[ -z $1 || $1 == '{}' ]]; then
                |   echo '{ "msg": "Hello from bash script!" }'
                |else
                |   echo $1 # echo the arguments back as the result
                |fi
            """.stripMargin.trim

        val python = """
                |#!/usr/bin/env python
                |from __future__ import print_function
                |import sys
                |print('hello stdout')
                |print('hello stderr', file=sys.stderr)
                |print(sys.argv[1])
            """.stripMargin.trim

        val perl = """
                |#!/usr/bin/env perl
                |print STDOUT "hello stdout\n";
                |print STDERR "hello stderr\n";
                |print $ARGV[0];
            """.stripMargin.trim

        // excluding perl as it not installed in alpine based image
        Seq(("bash", bash), ("python", python))
    }

    val stdUnicodeSamples = {
        // python 3 in base image
        val python = """
                |#!/usr/bin/env python
                |import json, sys
                |j = json.loads(sys.argv[1])
                |sep = j["delimiter"]
                |s = sep + " ☃ " + sep
                |print(s)
                |print(json.dumps({"winter": s}))
            """.stripMargin.trim

        Seq(("python", python))
    }

    /** Standard code samples, should print 'hello' to stdout and echo the input args. */
    val stdEnvSamples = {
        val bash = """
                |#!/bin/bash
                |echo "{ \
                |\"api_host\": \"$__OW_API_HOST\", \"api_key\": \"$__OW_API_KEY\", \
                |\"namespace\": \"$__OW_NAMESPACE\", \"action_name\": \"$__OW_ACTION_NAME\", \
                |\"activation_id\": \"$__OW_ACTIVATION_ID\", \"deadline\": \"$__OW_DEADLINE\" }"
            """.stripMargin.trim

        val python = """
                |#!/usr/bin/env python
                |import os
                |
                |print('{ "api_host": "%s", "api_key": "%s", "namespace": "%s", "action_name" : "%s", "activation_id": "%s", "deadline": "%s" }' % (
                |  os.environ['__OW_API_HOST'], os.environ['__OW_API_KEY'],
                |  os.environ['__OW_NAMESPACE'], os.environ['__OW_ACTION_NAME'],
                |  os.environ['__OW_ACTIVATION_ID'], os.environ['__OW_DEADLINE']))
            """.stripMargin.trim

        val perl = """
                |#!/usr/bin/env perl
                |$a = $ENV{'__OW_API_HOST'};
                |$b = $ENV{'__OW_API_KEY'};
                |$c = $ENV{'__OW_NAMESPACE'};
                |$d = $ENV{'__OW_ACTION_NAME'};
                |$e = $ENV{'__OW_ACTIVATION_ID'};
                |$f = $ENV{'__OW_DEADLINE'};
                |print "{ \"api_host\": \"$a\", \"api_key\": \"$b\", \"namespace\": \"$c\", \"action_name\": \"$d\", \"activation_id\": \"$e\", \"deadline\": \"$f\" }";
            """.stripMargin.trim

        // excluding perl as it not installed in alpine based image
        Seq(("bash", bash), ("python", python))
    }

    behavior of "openwhisk/dockerskeleton"

    it should "run sample without init" in {
        val (out, err) = withActionContainer() { c =>
            val (runCode, out) = c.run(JsObject())
            runCode should be(200)
            out should be(Some(JsObject("error" -> JsString("This is a stub action. Replace it with custom logic."))))
        }

        checkStreams(out, err, {
            case (o, _) => o should include("This is a stub action")
        })
    }

    it should "run sample with 'null' init" in {
        val (out, err) = withActionContainer() { c =>
            val (initCode, _) = c.init(initPayload(null))
            initCode should be(200)

            val (runCode, out) = c.run(JsObject())
            runCode should be(200)
            out should be(Some(JsObject("error" -> JsString("This is a stub action. Replace it with custom logic."))))
        }

        checkStreams(out, err, {
            case (o, _) => o should include("This is a stub action")
        })
    }

    it should "run sample with init that does nothing" in {
        val (out, err) = withActionContainer() { c =>
            val (initCode, _) = c.init(JsObject())
            initCode should be(200)
            val (runCode, out) = c.run(JsObject())
            runCode should be(200)
            out should be(Some(JsObject("error" -> JsString("This is a stub action. Replace it with custom logic."))))
        }

        checkStreams(out, err, {
            case (o, _) => o should include("This is a stub action")
        })
    }

    it should "respond with 404 for bad run argument" in {
        val (out, err) = withActionContainer() { c =>
            val (runCode, out) = c.run(runPayload(JsString("A")))
            runCode should be(404)
        }

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

    it should "fail to run a bad script" in {
        val (out, err) = withActionContainer() { c =>
            val (initCode, _) = c.init(initPayload(""))
            initCode should be(200)
            val (runCode, out) = c.run(JsNull)
            runCode should be(502)
            out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary."))))
        }

        checkStreams(out, err, {
            case (o, _) => o should include("error")
        })
    }

    it should "extract and run a compatible zip exec" in {
        val zip = FileUtils.readFileToByteArray(new File(TestUtils.getTestActionFilename("blackbox.zip")))
        val contents = Base64.getEncoder.encodeToString(zip)

        val (out, err) = withActionContainer() { c =>
            val (initCode, err) = c.init(JsObject("value" -> JsObject("code" -> JsString(contents), "binary" -> JsBoolean(true))))
            initCode should be(200)
            val (runCode, out) = c.run(JsObject())
            runCode should be(200)
            out.get should be(JsObject("msg" -> JsString("hello zip")))
        }

        checkStreams(out, err, {
            case (o, e) =>
                o shouldBe "This is an example zip used with the docker skeleton action."
                e shouldBe empty
        })
    }

    testNotReturningJson(codeNotReturningJson, checkResultInLogs = true)
    testEcho(stdCodeSamples)
    testUnicode(stdUnicodeSamples)
    testEnv(stdEnvSamples)
}

trait BasicActionRunnerTests extends ActionProxyContainerTestUtils {
    def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit): (String, String)

    /**
     * Runs tests for actions which do not return a dictionary and confirms expected error messages.
     * @param codeNotReturningJson code to execute, should not return a JSON object
     * @param checkResultInLogs should be true iff the result of the action is expected to appear in stdout or stderr
     */
    def testNotReturningJson(codeNotReturningJson: String, checkResultInLogs: Boolean = true) = {
        it should "run and report an error for script not returning a json object" in {
            val (out, err) = withActionContainer() { c =>
                val (initCode, _) = c.init(initPayload(codeNotReturningJson))
                initCode should be(200)
                val (runCode, out) = c.run(JsObject())
                runCode should be(502)
                out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary."))))
            }

            checkStreams(out, err, {
                case (o, e) =>
                    if (checkResultInLogs) {
                        (o + e) should include("not a json object")
                    } else {
                        o shouldBe empty
                        e shouldBe empty
                    }
            })
        }
    }

    /**
     * Runs tests for code samples which are expected to echo the input arguments
     * and print hello [stdout, stderr].
     */
    def testEcho(stdCodeSamples: Seq[(String, String)]) = {
        stdCodeSamples.foreach { s =>
            it should s"run a ${s._1} script" in {
                val argss = List(
                    JsObject("string" -> JsString("hello")),
                    JsObject("string" -> JsString("❄ ☃ ❄")),
                    JsObject("numbers" -> JsArray(JsNumber(42), JsNumber(1))),
                    // JsObject("boolean" -> JsBoolean(true)), // fails with swift3 returning boolean: 1
                    JsObject("object" -> JsObject("a" -> JsString("A"))))

                val (out, err) = withActionContainer() { c =>
                    val (initCode, _) = c.init(initPayload(s._2))
                    initCode should be(200)

                    for (args <- argss) {
                        val (runCode, out) = c.run(runPayload(args))
                        runCode should be(200)
                        out should be(Some(args))
                    }
                }

                checkStreams(out, err, {
                    case (o, e) =>
                        o should include("hello stdout")
                        e should include("hello stderr")
                }, argss.length)
            }
        }
    }

    def testUnicode(stdUnicodeSamples: Seq[(String, String)]) = {
        stdUnicodeSamples.foreach { s =>
            it should s"run a ${s._1} action and handle unicode in source, input params, logs, and result" in {
                val (out, err) = withActionContainer() { c =>
                    val (initCode, _) = c.init(initPayload(s._2))
                    initCode should be(200)

                    val (runCode, runRes) = c.run(runPayload(JsObject("delimiter" -> JsString("❄"))))
                    runRes.get.fields.get("winter") shouldBe Some(JsString("❄ ☃ ❄"))
                }

                checkStreams(out, err, {
                    case (o, _) =>
                        o.toLowerCase should include("❄ ☃ ❄")
                })
            }
        }
    }

    /** Runs tests for code samples which are expected to return the expected standard environment {auth, edge}. */
    def testEnv(stdEnvSamples: Seq[(String, String)], enforceEmptyOutputStream: Boolean = true, enforceEmptyErrorStream: Boolean = true) = {
        stdEnvSamples.foreach { s =>
            it should s"run a ${s._1} script 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) = withActionContainer(env.take(1).toMap) { c =>
                    val (initCode, _) = c.init(initPayload(s._2))
                    initCode should be(200)

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

                    }
                }

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