/*
 * 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 = main.capitalize
    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}.go") -> 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.mkBase64Zip(goCompiler, helloSrc("main"), "main")

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


  it should "accept a src main action " in {
    var src = ExeBuilder.mkBase64Src(helloSrc("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"))
    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"))
    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"))
    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.go") ->
          """
          |package main
          |import "hello"
          |func Main(args map[string]interface{})map[string]interface{} {
          | return hello.Hello(args)
          |}
        """.stripMargin
      )
    )
    withActionLoopContainer { c =>
      c.init(initPayload(src))._1 shouldBe (200)
      c.run(helloMsg()) should be(okMsg("hello-Hello", "Hello, Demo!"))
    }
  }
}
