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