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

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import common.WskActorSystem
import actionContainers.{ActionContainer, BasicActionRunnerTests}
import actionContainers.ActionContainer.withContainer
import actionContainers.ResourceHelpers.ZipBuilder
import actionContainers.ResourceHelpers
import java.nio.file.FileSystems;
import spray.json._

@RunWith(classOf[JUnitRunner])
class Ruby25ActionContainerTests extends BasicActionRunnerTests with WskActorSystem {
  // note: "out" will not be empty as the Webrick outputs a message during the boot and after the boot
  val enforceEmptyOutputStream = false

  lazy val ruby25ContainerImageName = "action-ruby-v2.5"

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

  def withRuby25Container(code: ActionContainer => Unit) = withActionContainer()(code)

  behavior of ruby25ContainerImageName

  override val testNoSourceOrExec = TestConfig("")

  override val testEcho = {
    TestConfig("""
                 |def main(args)
                 |  puts 'hello stdout'
                 |  warn 'hello stderr'
                 |  args
                 |end
               """.stripMargin)
  }

  override val testNotReturningJson = {
    TestConfig(
      """
       |def main(args)
       |  "not a json object"
       |end
     """.stripMargin,
      enforceEmptyOutputStream = enforceEmptyOutputStream,
      enforceEmptyErrorStream = false)
  }

  override val testInitCannotBeCalledMoreThanOnce = {
    TestConfig(
      """
        |def main(args)
        |  args
        |end
      """.stripMargin,
      enforceEmptyOutputStream = enforceEmptyOutputStream)
  }

  override val testEntryPointOtherThanMain = {
    TestConfig(
      """
        |def niam(args)
        |  args
        |end
      """.stripMargin,
      main = "niam",
      enforceEmptyOutputStream = enforceEmptyOutputStream)
  }

  override val testUnicode = {
    TestConfig("""
         |def main(args)
         |  str = args['delimiter'] + " ☃ " + args['delimiter']
         |  print str + "\n"
         |  {"winter" => str}
         |end
         """.stripMargin.trim)
  }

  override val testEnv = {
    TestConfig(
      """
        |def main(args)
        |  {
        |       "env" => ENV,
        |       "api_host" => ENV['__OW_API_HOST'],
        |       "api_key" => ENV['__OW_API_KEY'],
        |       "namespace" => ENV['__OW_NAMESPACE'],
        |       "action_name" => ENV['__OW_ACTION_NAME'],
        |       "activation_id" => ENV['__OW_ACTIVATION_ID'],
        |       "deadline" => ENV['__OW_DEADLINE']
        |  }
        |end
      """.stripMargin.trim,
      enforceEmptyOutputStream = enforceEmptyOutputStream)
  }

  override val testLargeInput = {
    TestConfig("""
        |def main(args)
        |  args
        |end
      """.stripMargin)
  }

  it should "fail to initialize with bad code" in {
    val (out, err) = withRuby25Container { c =>
      val code = """
                | 10 PRINT "Hello world!"
                | 20 GOTO 10
            """.stripMargin

      val (initCode, error) = c.init(initPayload(code))
      initCode should not be (200)
      error shouldBe a[Some[_]]
      error.get shouldBe a[JsObject]
      error.get.fields("error").toString should include("failed to parse the input code")
    }

    // Somewhere, the logs should mention an error occurred.
    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("invalid")
        (o + e).toLowerCase should include("parse")
    })
  }

  it should "return some error on action error" in {
    val (out, err) = withRuby25Container { c =>
      val code = """
                | def main(args)
                |   raise Exception.new("nooooo")
                | end
            """.stripMargin

      val (initCode, _) = c.init(initPayload(code))
      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
    // runRes.get.fields("error").toString.toLowerCase should include("nooooo")
    }

    // Somewhere, the logs should be the error text
    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("nooooo")
    })

  }

  it should "support application errors" in {
    withRuby25Container { c =>
      val code = """
                | def main(args)
                |   { "error" => "sorry" }
                | end
            """.stripMargin;

      val (initCode, error) = c.init(initPayload(code))
      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
      runRes.get.fields("error").toString.toLowerCase should include("sorry")
    }
  }

  it should "fail gracefully when an action has a TypeError exception" in {
    val (out, err) = withRuby25Container { c =>
      val code = """
                | def main(args)
                |   eval "class ENV\nend"
                |   { "hello" => "world" }
                | end
            """.stripMargin;

      val (initCode, _) = c.init(initPayload(code))
      initCode should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runCode should be(502)

      runRes shouldBe defined
      runRes.get.fields.get("error") shouldBe defined
      runRes.get.fields("error").toString should include("An error occurred running the action")
    }

    // Somewhere, the logs should be the error text
    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("typeerror")
    })
  }

  it should "support the documentation examples (1)" in {
    val (out, err) = withRuby25Container { c =>
      val code = """
                | def main(params)
                |   if (params['payload'] == 0) then
                |     return {}
                |   elsif params['payload'] == 1 then
                |     return {'payload' => 'Hello, World!'} # indicates normal completion
                |   elsif params['payload'] == 2 then
                |     return {'error' => 'payload must be 0 or 1'}  # indicates abnormal completion
                |   end
                | end
            """.stripMargin

      c.init(initPayload(code))._1 should be(200)

      val (c1, r1) = c.run(runPayload(JsObject("payload" -> JsNumber(0))))
      val (c2, r2) = c.run(runPayload(JsObject("payload" -> JsNumber(1))))
      val (c3, r3) = c.run(runPayload(JsObject("payload" -> JsNumber(2))))

      c1 should be(200)
      r1 should be(Some(JsObject()))

      c2 should be(200)
      r2 should be(Some(JsObject("payload" -> JsString("Hello, World!"))))

      c3 should be(200) // application error, not container or system
      r3.get.fields.get("error") shouldBe Some(JsString("payload must be 0 or 1"))
    }
  }

  it should "have mechanize and activesupport gems available" in {
    // GIVEN that it should "error when requiring a non-existent package" (see test above for this)
    val (out, err) = withRuby25Container { c =>
      val code = """
                | require 'mechanize'
                | require 'active_support'
                | def main(args)
                |   Mechanize.class
                |   ActiveSupport.class
                |   {}
                | end
            """.stripMargin

      val (initCode, _) = c.init(initPayload(code))

      initCode should be(200)

      // WHEN I run an action that calls a Guzzle & a Uuid method
      val (runCode, out) = c.run(runPayload(JsObject()))

      // THEN it should pass only when these packages are available
      runCode should be(200)
    }
  }

  it should "support large-ish actions" in {
    val thought = " I took the one less traveled by, and that has made all the difference."
    val assignment = "    x = \"" + thought + "\";\n"

    val code = """
            | def main(args)
            |   x = "hello"
            """.stripMargin + (assignment * 7000) + """
            |   x = "world"
            |   { "message" => x }
            | end
            """.stripMargin

    // Lest someone should make it too easy.
    code.length should be >= 500000

    val (out, err) = withRuby25Container { c =>
      c.init(initPayload(code))._1 should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))

      runCode should be(200)
      runRes.get.fields.get("message") shouldBe defined
      runRes.get.fields.get("message") shouldBe Some(JsString("world"))
    }
  }

  val exampleOutputDotRuby: String = """
        | def output(data)
        |   {'result' => data}
        | end
    """.stripMargin

  it should "support zip-encoded packages" in {
    val srcs = Seq(
      Seq("output.rb") -> exampleOutputDotRuby,
      Seq("main.rb") -> """
                | require __dir__ + '/output.rb'
                | def main(args)
                |   name = args['name'] || 'stranger'
                |   output(name)
                | end
            """.stripMargin)

    val code = ZipBuilder.mkBase64Zip(srcs)

    val (out, err) = withRuby25Container { c =>
      c.init(initPayload(code))._1 should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))

      runCode should be(200)
      runRes.get.fields.get("result") shouldBe defined
      runRes.get.fields.get("result") shouldBe Some(JsString("stranger"))
    }
  }

  it should "support zip-encoded packages without directory entries" in {
    val path = FileSystems.getDefault().getPath("dat", "without_dir_entries.zip");
    val code = ResourceHelpers.readAsBase64(path)

    val (out, err) = withRuby25Container { c =>
      c.init(initPayload(code))._1 should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))

      runCode should be(200)
      runRes.get.fields.get("greeting") shouldBe defined
      runRes.get.fields.get("greeting") shouldBe Some(JsString("Hello stranger!"))
    }
  }

  it should "fail gracefully on invalid zip files" in {
    // Some text-file encoded to base64.
    val code = "Q2VjaSBuJ2VzdCBwYXMgdW4gemlwLgo="

    val (out, err) = withRuby25Container { c =>
      val (initCode, error) = c.init(initPayload(code))
      initCode should not be (200)
      error shouldBe a[Some[_]]
      error.get shouldBe a[JsObject]
      error.get.fields("error").toString should include("failed to open zip file")
    }

    // Somewhere, the logs should mention the failure
    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("error")
        (o + e).toLowerCase should include("failed to open zip file")
    })
  }

  it should "fail gracefully on valid zip files that are not actions" in {
    val srcs = Seq(Seq("hello") -> """
                | Hello world!
            """.stripMargin)

    val code = ZipBuilder.mkBase64Zip(srcs)

    val (out, err) = withRuby25Container { c =>
      c.init(initPayload(code))._1 should not be (200)
    }

    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("error")
        (o + e).toLowerCase should include("zipped actions must contain main.rb at the root.")
    })
  }

  it should "fail gracefully on valid zip files with invalid code in main.rb" in {
    val (out, err) = withRuby25Container { c =>
      val srcs = Seq(Seq("main.rb") -> """
                    | 10 PRINT "Hello world!"
                    | 20 GOTO 10
                """.stripMargin)

      val code = ZipBuilder.mkBase64Zip(srcs)

      val (initCode, error) = c.init(initPayload(code))
      initCode should not be (200)
      error shouldBe a[Some[_]]
      error.get shouldBe a[JsObject]
      error.get.fields("error").toString should include("failed to parse the input code")
    }

    // Somewhere, the logs should mention an error occurred.
    checkStreams(out, err, {
      case (o, e) =>
        (o + e).toLowerCase should include("invalid")
        (o + e).toLowerCase should include("parse")
    })
  }

  it should "support zipped actions using non-default entry point" in {
    val srcs = Seq(Seq("main.rb") -> """
                | def niam(args)
                |   { :result => "it works" }
                | end
            """.stripMargin)

    val code = ZipBuilder.mkBase64Zip(srcs)

    withRuby25Container { c =>
      c.init(initPayload(code, main = "niam"))._1 should be(200)

      val (runCode, runRes) = c.run(runPayload(JsObject()))
      runRes.get.fields.get("result") shouldBe Some(JsString("it works"))
    }
  }

}
