/*
 * 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 java.util.concurrent.TimeoutException
import actionContainers.{ActionContainer, ActionProxyContainerTestUtils}
import actionContainers.ActionContainer.withContainer
import common.WskActorSystem
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

//import spray.json.JsNumber
//import spray.json.JsBoolean
import spray.json.{JsObject, JsString}

@RunWith(classOf[JUnitRunner])
class ActionLoopGoContainerTests
    extends ActionProxyContainerTestUtils
    with WskActorSystem {

  import GoResourceHelpers._

  val goCompiler = "actionloop-golang-v1.11"
  val image = goCompiler

  def withActionLoopContainer(code: ActionContainer => Unit) =
    withContainer(image)(code)

  behavior of image

  def helloGo(main: String, pkg: String = "main") = {
    val func = if (main == "main") "Main" else main
    s"""|package ${pkg}
        |
        |import "fmt"
        |
        |func ${func}(obj map[string]interface{}) map[string]interface{} {
        |	 name, ok := obj["name"].(string)
        |	 if !ok {
        |	  	name = "Stranger"
        |	 }
        |	 fmt.Printf("name=%s\\n", name)
        |  msg := make(map[string]interface{})
        |	 msg["${pkg}-${main}"] = "Hello, " + name + "!"
        |	 return msg
        |}
        |""".stripMargin
  }

  private def helloSrc(main: String) = Seq(
    Seq(s"${main}") -> helloGo(main)
  )

  private def helloMsg(name: String = "Demo") =
    runPayload(JsObject("name" -> JsString(name)))

  private def okMsg(key: String, value: String) =
    200 -> Some(JsObject(key -> JsString(value)))

  it should "run sample with init that does nothing" in {
    val (out, err) = withActionLoopContainer { c =>
      c.init(JsObject())._1 should be(403)
      c.run(JsObject())._1 should be(500)
    }
  }

  it should "accept a binary main" in {
    val exe = ExeBuilder.mkBase64Exe(goCompiler, helloSrc("main"), "main")

    withActionLoopContainer { c =>
      c.init(initPayload(exe))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-main", "Hello, Demo!"))
    }
  }

  //def pr(x: Any) = { println(x) ; x}

  it should "accept a zipped main binary" in {
    val zip = ExeBuilder.mkBase64Zip(goCompiler, helloSrc("main"), "main")
    withActionLoopContainer { c =>
      c.init(initPayload(zip))._1 should be(200)
      c.run(helloMsg()) should be(okMsg("main-main", "Hello, Demo!"))
    }
  }

  it should "accept a binary not-main" in {
    val exe = ExeBuilder.mkBase64Exe(goCompiler, helloSrc("hello"), "hello")
    withActionLoopContainer { c =>
      c.init(initPayload(exe, "hello"))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-hello", "Hello, Demo!"))
    }
  }

  it should "accept a zipped binary not-main" in {
    val zip = ExeBuilder.mkBase64Zip(goCompiler, helloSrc("hello"), "hello")
    withActionLoopContainer { c =>
      c.init(initPayload(zip, "hello"))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-hello", "Hello, Demo!"))
    }
  }

  it should "accept a src main action " in {
    var src = ExeBuilder.mkBase64Src(helloSrc("main"), "main")
    withActionLoopContainer { c =>
      c.init(initPayload(src))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-main", "Hello, Demo!"))
    }
  }

  it should "accept a src not-main action " in {
    var src = ExeBuilder.mkBase64Src(helloSrc("hello"), "hello")
    withActionLoopContainer { c =>
      c.init(initPayload(src, "hello"))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-hello", "Hello, Demo!"))
    }
  }

  it should "accept a zipped src main action" in {
    var src = ExeBuilder.mkBase64SrcZip(helloSrc("main"), "main")
    withActionLoopContainer { c =>
      c.init(initPayload(src))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-main", "Hello, Demo!"))
    }
  }

  it should "accept a zipped src not-main action" in {
    var src = ExeBuilder.mkBase64SrcZip(helloSrc("hello"), "hello")
    withActionLoopContainer { c =>
      c.init(initPayload(src, "hello"))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("main-hello", "Hello, Demo!"))
    }
  }

  it should "deploy a zip main src with subdir" in {
    var src = ExeBuilder.mkBase64SrcZip(
      Seq(
        Seq("hello", "hello.go") -> helloGo("Hello", "hello"),
        Seq("main") ->
          """
          |package main
          |import "hello"
          |func Main(args map[string]interface{})map[string]interface{} {
          | return hello.Hello(args)
          |}
        """.stripMargin
      ),
      "main"
    )
    withActionLoopContainer { c =>
      c.init(initPayload(src))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("hello-Hello", "Hello, Demo!"))
    }
  }
}
