/*
 * Copyright 2015-2016 IBM Corporation
 *
 * Licensed 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 whisk.core.controller.test.migration

import scala.Vector

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

import common.TestHelpers
import common.WskTestHelpers
import spray.http.StatusCodes.OK
import spray.httpx.SprayJsonSupport.sprayJsonMarshaller
import spray.httpx.SprayJsonSupport.sprayJsonUnmarshaller
import spray.json.DefaultJsonProtocol.RootJsObjectFormat
import spray.json.DefaultJsonProtocol.listFormat
import spray.json.DefaultJsonProtocol.StringJsonFormat
import spray.json.DefaultJsonProtocol.vectorFormat
import spray.json.JsObject
import spray.json.pimpAny
import spray.json.pimpString

import whisk.core.controller.WhiskActionsApi
import whisk.core.controller.test.ControllerTestCommon
import whisk.core.entity.AuthKey
import whisk.core.entity.EntityName
import whisk.core.entity.EntityPath
import whisk.core.entity.Exec
import whisk.core.entity.Parameters
import whisk.core.entity.Subject
import whisk.core.entity.WhiskAction
import whisk.core.entity.WhiskActionPut
import whisk.core.entity.WhiskAuth

/**
 * Tests migration of a new implementation of sequences: old style sequences can be updated and retrieved - standalone tests
 */
@RunWith(classOf[JUnitRunner])
class SequenceActionApiMigrationTests extends ControllerTestCommon
    with WhiskActionsApi
    with TestHelpers
    with WskTestHelpers {

    behavior of "Sequence Action API Migration"

    val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
    val namespace = EntityPath(creds.subject.asString)
    val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
    def aname = MakeName.next("seq_migration_tests")

    private def seqParameters(seq: Vector[String]) = Parameters("_actions", seq.toJson)

    it should "list old-style sequence action with explicit namespace" in {
        implicit val tid = transid()
        val sequence = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c").map(stringToFullyQualifiedName(_))
        val actions = (1 to 2).map { i =>
            WhiskAction(namespace, aname, Exec.sequence(sequence))
        }.toList
        actions foreach { put(entityStore, _) }
        waitOnView(entityStore, WhiskAction, namespace, 2)
        Get(s"/$namespace/${collection.path}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[List[JsObject]]

            actions.length should be(response.length)
            actions forall { a => response contains a.summaryAsJson } should be(true)
        }
    }

    it should "get old-style sequence action by name in default namespace" in {
        implicit val tid = transid()
        val sequence = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c").map(stringToFullyQualifiedName(_))
        val action = WhiskAction(namespace, aname, Exec.sequence(sequence))
        put(entityStore, action)
        Get(s"$collectionPath/${action.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskAction]
            response should be(action)
        }
    }

    // this test is a repeat from ActionsApiTest BUT with old style sequence
    it should "preserve new parameters when changing old-style sequence action to non sequence" in {
        implicit val tid = transid()
        val components = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c")
        val sequence = components.map(stringToFullyQualifiedName(_))
        val action = WhiskAction(namespace, aname, Exec.sequence(sequence), seqParameters(components))
        val content = WhiskActionPut(Some(Exec.js("")), parameters = Some(Parameters("a", "A")))
        put(entityStore, action, false)

        // create an action sequence
        Put(s"$collectionPath/${action.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            deleteAction(action.docid)
            status should be(OK)
            val response = responseAs[WhiskAction]
            response.exec.kind should be(Exec.NODEJS)
            response.parameters should be(Parameters("a", "A"))
        }
    }

    // this test is a repeat from ActionsApiTest BUT with old style sequence
    it should "reset parameters when changing old-style sequence action to non sequence" in {
        implicit val tid = transid()
        val components = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c")
        val sequence = components.map(stringToFullyQualifiedName(_))
        val action = WhiskAction(namespace, aname, Exec.sequence(sequence), seqParameters(components))
        val content = WhiskActionPut(Some(Exec.js("")))
        put(entityStore, action, false)

        // create an action sequence
        Put(s"$collectionPath/${action.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            deleteAction(action.docid)
            status should be(OK)
            val response = responseAs[WhiskAction]
            response.exec.kind should be(Exec.NODEJS)
            response.parameters shouldBe Parameters()
        }
    }

    it should "update old-style sequence action with new annotations" in {
        implicit val tid = transid()
        val components = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c")
        val sequence = components.map(stringToFullyQualifiedName(_))
        val action = WhiskAction(namespace, aname, Exec.sequence(sequence))
        val content = """{"annotations":[{"key":"old","value":"new"}]}""".parseJson.asJsObject
        put(entityStore, action, false)

        // create an action sequence
        Put(s"$collectionPath/${action.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            deleteAction(action.docid)
            status should be(OK)
            val response = responseAs[String]
            // contains the action
            components map {c => response should include(c)}
            // contains the annotations
            response should include("old")
            response should include("new")
        }
    }

    it should "update an old-style sequence with new sequence" in {
        implicit val tid = transid()
        // old sequence
        val seqName = EntityName(s"${aname}_new")
        val oldComponents = Vector("/_/a", "/_/x/b", "/n/a", "/n/x/c").map(stringToFullyQualifiedName(_))
        val oldSequence = WhiskAction(namespace, seqName, Exec.sequence(oldComponents))
        put(entityStore, oldSequence)

        // new sequence
        val limit = 5 // count of bogus actions in sequence
        val bogus = s"${aname}_bogus"
        val bogusActionName = s"/_/${bogus}"   // test that default namespace gets properly replaced
        // put the action in the entity store so it exists
        val bogusAction = WhiskAction(namespace, EntityName(bogus), Exec.js("??"), Parameters("x", "y"))
        put(entityStore, bogusAction)
        val sequence = for (i <- 1 to limit) yield stringToFullyQualifiedName(bogusActionName)
        val seqAction = WhiskAction(namespace, seqName, Exec.sequence(sequence.toVector))
        val content = WhiskActionPut(Some(seqAction.exec), Some(Parameters()))

        // update an action sequence
        Put(s"$collectionPath/${seqName}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskAction]
            response.exec.kind should be(Exec.SEQUENCE)
            response.limits should be(seqAction.limits)
            response.publish should be(seqAction.publish)
            response.version should be(seqAction.version.upPatch)
        }
    }
}
