/*
 * 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 org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

import ActionContainer.withContainer
import common.WskActorSystem
import spray.json.JsObject
import spray.json.JsString
import common.TestUtils

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

    // note: "out" will likely not be empty in some swift build as the compiler
    // prints status messages and there doesn't seem to be a way to quiet them
    val enforceEmptyOutputStream = false
    lazy val swiftContainerImageName = "swift3action"
    lazy val envCode = makeEnvCode("ProcessInfo.processInfo")

    def makeEnvCode(processInfo: String) = ("""
         |func main(args: [String: Any]) -> [String: Any] {
         |     let env = """ + processInfo + """.environment
         |     var a = "???"
         |     var b = "???"
         |     var c = "???"
         |     var d = "???"
         |     var e = "???"
         |     var f = "???"
         |     if let v : String = env["__OW_API_HOST"] {
         |         a = "\(v)"
         |     }
         |     if let v : String = env["__OW_API_KEY"] {
         |         b = "\(v)"
         |     }
         |     if let v : String = env["__OW_NAMESPACE"] {
         |         c = "\(v)"
         |     }
         |     if let v : String = env["__OW_ACTION_NAME"] {
         |         d = "\(v)"
         |     }
         |     if let v : String = env["__OW_ACTIVATION_ID"] {
         |         e = "\(v)"
         |     }
         |     if let v : String = env["__OW_DEADLINE"] {
         |         f = "\(v)"
         |     }
         |     return ["api_host": a, "api_key": b, "namespace": c, "action_name": d, "activation_id": e, "deadline": f]
         |}
         """).stripMargin

    lazy val errorCode = """
                | // You need an indirection, or swiftc detects the div/0
                | // at compile-time. Smart.
                | func div(x: Int, y: Int) -> Int {
                |     return x/y
                | }
                | func main(args: [String: Any]) -> [String: Any] {
                |     return [ "divBy0": div(x:5, y:0) ]
                | }
            """.stripMargin

    // Helpers specific to swift actions
    override def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit) = {
        withContainer(swiftContainerImageName, env)(code)
    }

    behavior of swiftContainerImageName

    // remove this test: it will not even compile under Swift 3 anymore
    // so it should not be possible to write an action that does not return
    // a [String:Any]
    /*testNotReturningJson(
        """
        |func main(args: [String: Any]) -> String {
        |    return "not a json object"
        |}
        """.stripMargin)
    */

    testEcho(Seq {
        ("swift", """
         | import Foundation
         |
         | extension FileHandle : TextOutputStream {
         |     public func write(_ string: String) {
         |         guard let data = string.data(using: .utf8) else { return }
         |         self.write(data)
         |     }
         | }
         |
         | func main(args: [String: Any]) -> [String: Any] {
         |     print("hello stdout")
         |     var standardError = FileHandle.standardError
         |     print("hello stderr", to: &standardError)
         |     return args
         | }
        """.stripMargin)
    })

    testUnicode(Seq {
        ("swift", """
         | func main(args: [String: Any]) -> [String: Any] {
         |     if let str = args["delimiter"] as? String {
         |         let msg = "\(str) ☃ \(str)"
         |         print(msg)
         |         return [ "winter" : msg ]
         |     } else {
         |         return [ "error" : "no delimiter" ]
         |     }
         | }
         """.stripMargin.trim)
    })

    testEnv(Seq {
        ("swift", envCode)
    }, enforceEmptyOutputStream)

    it should "support actions using non-default entry points" in {
        withActionContainer() { c =>
            val code = """
                | func niam(args: [String: Any]) -> [String: Any] {
                |     return [ "result": "it works" ]
                | }
                |""".stripMargin

            val (initCode, initRes) = c.init(initPayload(code, main = "niam"))
            initCode should be(200)

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

    it should "return some error on action error" in {
        val (out, err) = withActionContainer() { c =>
            val code = errorCode

            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
        }

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

    it should "log compilation errors" in {
        val (out, err) = withActionContainer() { c =>
            val code = """
              | 10 PRINT "Hello!"
              | 20 GOTO 10
            """.stripMargin

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

        checkStreams(out, err, {
            case (o, e) =>
                if (enforceEmptyOutputStream) o shouldBe empty
                e.toLowerCase should include("error")
        })
    }

    it should "support application errors" in {
        val (out, err) = withActionContainer() { c =>
            val code = """
                | func main(args: [String: Any]) -> [String: Any] {
                |     return [ "error": "sorry" ]
                | }
            """.stripMargin

            val (initCode, _) = 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 should be(Some(JsObject("error" -> JsString("sorry"))))
        }

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

    it should "support support multiple files in a zip file" in {
        val zip = new File(TestUtils.getTestActionFilename("multiSwift.zip")).toPath
        val code = ResourceHelpers.readAsBase64(zip)

        val (out, err) = withActionContainer() { c =>
            val (initCode, initRes) = c.init(initPayload(code))
            initCode should be(200)

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

            runCode should be(200)
            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
        }

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

    it should "support pre-compiled binary in a zip file" in {
        val zip = new File(TestUtils.getTestActionFilename("helloSwift.zip")).toPath
        val code = ResourceHelpers.readAsBase64(zip)

        val (out, err) = withActionContainer() { c =>
            val (initCode, initRes) = c.init(initPayload(code))
            initCode should be(200)

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

            runCode should be(200)
            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
        }

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

    it should "properly use KituraNet and Dispatch" in {
        val (out, err) = withActionContainer() { c =>
            val code = """
                | import KituraNet
                | import Foundation
                | import Dispatch
                | func main(args:[String: Any]) -> [String:Any] {
                |       let retries = 3
                |       var resp = [String:Any]()
                |       var attempts = 0
                |       if let url = args["getUrl"] as? String {
                |           while attempts < retries {
                |               let group = DispatchGroup()
                |               let queue = DispatchQueue.global(qos: .default)
                |               group.enter()
                |               queue.async {
                |                   HTTP.get(url, callback: { response in
                |                       if let response = response {
                |                           do {
                |                               var jsonData = Data()
                |                               try response.readAllData(into: &jsonData)
                |                               if let dic = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
                |                                   resp = dic
                |                               } else {
                |                                   resp = ["error":"response from server is not JSON"]
                |                               }
                |                           } catch {
                |                              resp["error"] = error.localizedDescription
                |                           }
                |                       }
                |                       group.leave()
                |                   })
                |               }
                |            switch group.wait(timeout: DispatchTime.distantFuture) {
                |                case DispatchTimeoutResult.success:
                |                    resp["attempts"] = attempts
                |                    return resp
                |                case DispatchTimeoutResult.timedOut:
                |                    attempts = attempts + 1
                |            }
                |        }
                |     }
                |     return ["status":"Exceeded \(retries) attempts, aborting."]
                | }
            """.stripMargin

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

            initCode should be(200)

            val argss = List(
                JsObject("getUrl" -> JsString("https://openwhisk.ng.bluemix.net/api/v1")))

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

        // in side try catch finally print (out file)
        // in catch block an error has occurred, get docker logs and print
        // throw

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

    it should "make Watson SDKs available to action authors" in {
        val (out, err) = withActionContainer() { c =>
            val code = """
                | import RestKit
                | import WeatherCompanyData
                | import AlchemyVision
                |
                | func main(args: [String:Any]) -> [String:Any] {
                |     return ["message": "I compiled and was able to import Watson SDKs"]
                | }
            """.stripMargin

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

            initCode should be(200)

            val (runCode, out) = c.run(runPayload(JsObject()))
            runCode should be(200)
        }

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