/*
 * 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 common

import scala.collection.mutable.ListBuffer
import scala.util.Failure
import scala.util.Try
import scala.concurrent.duration.Duration
import scala.concurrent.duration.DurationInt
import scala.language.postfixOps

import org.scalatest.Matchers

import TestUtils._
import spray.json._
import java.time.Instant

/**
 * Test fixture to ease cleaning of whisk entities created during testing.
 *
 * The fixture records the entities created during a test and when the test
 * completed, will delete them all.
 */
trait WskTestHelpers extends Matchers {
    type Assets = ListBuffer[(DeleteFromCollection, String, Boolean)]

    /**
     * Helper to register an entity to delete once a test completes.
     * The helper sanitizes (deletes) a previous instance of the entity if it exists
     * in given collection.
     *
     */
    class AssetCleaner(assetsToDeleteAfterTest: Assets, wskprops: WskProps) {
        def withCleaner[T <: DeleteFromCollection](cli: T, name: String, confirmDelete: Boolean = true)(
            cmd: (T, String) => RunResult): RunResult = {
            // sanitize (delete) if asset exists
            cli match {
                case _: WskPackage =>
                    val rr = cli.sanitize(name)(wskprops)
                    rr.exitCode match {
                        case CONFLICT =>
                            // retry sanitization on a package since there may be a list (view)
                            // operation that requires a retry for eventual consistency
                            whisk.utils.retry({
                                cli.sanitize(name)(wskprops)
                            }, 5, Some(1 second))
                        case _ => rr
                    }

                case _ => cli.sanitize(name)(wskprops)
            }

            assetsToDeleteAfterTest += ((cli, name, confirmDelete))
            cmd(cli, name)
        }
    }

    /**
     * Creates a test closure which records all entities created inside the test into a
     * list that is iterated at the end of the test so that these entities are deleted
     * (from most recently created to oldest).
     */
    def withAssetCleaner(wskprops: WskProps)(test: (WskProps, AssetCleaner) => Any) = {
        // create new asset list to track what must be deleted after test completes
        val assetsToDeleteAfterTest = new Assets()

        try {
            test(wskprops, new AssetCleaner(assetsToDeleteAfterTest, wskprops))
        } finally {
            // delete assets in reverse order so that was created last is deleted first
            val deletedAll = assetsToDeleteAfterTest.reverse map {
                case ((cli, n, delete)) => n -> Try {
                    if (delete) {
                        cli.delete(n)(wskprops)
                    } else {
                        cli.sanitize(n)(wskprops)
                    }
                }
            } forall {
                case (n, Failure(t)) =>
                    println(s"ERROR: deleting asset failed for $n: $t")
                    false
                case _ =>
                    true
            }
            assert(deletedAll, "some assets were not deleted")
        }
    }

    /**
     * An arbitrary response of a whisk action. Includes the result as a JsObject as the
     * structure of "result" is not defined.
     */
    case class CliActivationResponse(result: Option[JsObject], status: String, success: Boolean)

    object CliActivationResponse extends DefaultJsonProtocol {
        implicit val serdes = jsonFormat3(CliActivationResponse.apply)
    }

    /**
     * Activation record as it is returned by the CLI.
     */
    case class CliActivation(
        activationId: String,
        logs: Option[List[String]],
        response: CliActivationResponse,
        start: Long,
        end: Long,
        duration: Long,
        cause: Option[String],
        annotations: Option[List[JsObject]])

    object CliActivation extends DefaultJsonProtocol {
        implicit val serdes = jsonFormat8(CliActivation.apply)
    }

    /**
     * Extracts an activation id from a wsk command producing a RunResult with such an id.
     * If id is found, polls activations until one matching id is found. If found, pass
     * the activation to the post processor which then check for expected values.
     */
    def withActivation(
        wsk: WskActivation,
        run: RunResult,
        initialWait: Duration = 1 second,
        pollPeriod: Duration = 1 second,
        totalWait: Duration = 30 seconds)(
            check: CliActivation => Unit)(
                implicit wskprops: WskProps): Unit = {
        val activationId = wsk.extractActivationId(run)

        withClue(s"did not find an activation id in '$run'") {
            activationId shouldBe a[Some[_]]
        }

        val id = activationId.get
        val activation = wsk.waitForActivation(id, initialWait, pollPeriod, totalWait)
        if (activation.isLeft) {
            assert(false, s"error waiting for activation $id: ${activation.left.get}")
        } else try {
            check(activation.right.get.convertTo[CliActivation])
        } catch {
            case error: Throwable =>
                println(s"check failed for activation $id: ${activation.right.get}")
                throw error
        }
    }

    /**
     * Polls until it finds {@code N} activationIds from an entity. Asserts the count
     * of the activationIds actually equal {@code N}. Takes a {@code since} parameter
     * defining the oldest activationId to consider valid.
     */
    def withActivationsFromEntity(
        wsk: WskActivation,
        entity: String,
        N: Int = 1,
        since: Option[Instant] = None,
        pollPeriod: Duration = 1 second,
        totalWait: Duration = 30 seconds)(
            check: Seq[CliActivation] => Unit)(
                implicit wskprops: WskProps): Unit = {

        val activationIds = wsk.pollFor(N, Some(entity), since = since, retries = (totalWait / pollPeriod).toInt, pollPeriod = pollPeriod)
        withClue(s"did not find $N activations for $entity since $since") {
            activationIds.length shouldBe N
        }

        val parsed = activationIds.map { id =>
            wsk.parseJsonString(wsk.get(id).stdout).convertTo[CliActivation]
        }
        try {
            check(parsed)
        } catch {
            case error: Throwable =>
                println(s"check failed for activations $activationIds: ${parsed}")
                throw error
        }
    }

    /**
     * In the case that test throws an exception, print stderr and stdout
     * from the provided RunResult.
     */
    def withPrintOnFailure(runResult: RunResult)(test: () => Unit) {
        try {
            test()
        } catch {
            case error: Throwable =>
                println(s"[stderr] ${runResult.stderr}")
                println(s"[stdout] ${runResult.stdout}")
                throw error
        }
    }
}
