package controllers

import com.daumkakao.s2graph.core.Management._
import com.daumkakao.s2graph.core._
import com.daumkakao.s2graph.rest.actors._
import com.daumkakao.s2graph.rest.config.Config
import org.specs2.matcher.Matchers
import org.specs2.mutable.Specification
import play.api.libs.json.{ JsArray, JsObject, Json }
import play.api.test.Helpers._
import play.api.test._
import com.wordnik.swagger.annotations.Api
import scala.Array.canBuildFrom
import scala.concurrent.ExecutionContext

/**
 * Graph Query test case specification
 * @author June.k( Junki Kim, june.k@daumkakao.com )
 * @since 2015. 1. 2.
 */

class QuerySpec extends QuerySpecificationBase with Matchers {
  def spec =
    new Specification {
      sequential

      "Application" should {
        "[getEdgesGrouped query] test (function + response format check)" in new WithApplication {
          val simpleQuery =
            s"""
      {
          "srcVertices": [
              {
                  "serviceName": "$testServiceName",
                  "columnName": "$testColumnName",
                  "id": ${fromVertexIds(0)}
              }
          ],
          "steps": [
              [
                  {
                      "label": "$testLabelName",
                      "direction": "out",
                      "offset": 0,
                      "limit": 10
                  }
              ]
          ]
      }
       """.stripMargin

          val acts = route(FakeRequest(POST, "/graphs/getEdgesGrouped").withJsonBody(Json.parse(simpleQuery))).get

          //    logger.debug(s">> Social Controller test Acts result : ${contentAsJson(acts)}")
          status(acts) must equalTo(OK)
          contentType(acts) must beSome.which(_ == "text/plain")
          val jsRslt = contentAsJson(acts)
          println("======")
          println(jsRslt)
          println("======")
          jsRslt.as[JsObject].keys.contains("size") must equalTo(true)
          jsRslt.as[JsObject].keys.contains("results") must equalTo(true)
          (jsRslt \ "size").as[Int] must greaterThan(0)
          ((jsRslt \ "results") \\ "name").seq(0).as[String] must equalTo("user_id")
          (((jsRslt \ "results") \\ "aggr").seq(0).as[JsObject] \ "ids").as[JsArray].value.map(_.as[String]).toList should containAllOf(Seq[String](fromVertexIds(0).toString))
        }

        "[getEdgesGroupedExcluded query] test (function + response format check)" in new WithApplication {
          val simpleQuery =
            s"""
      {
          "srcVertices": [
              {
                  "serviceName": "$testServiceName",
                  "columnName": "$testColumnName",
                  "id": ${fromVertexIds(0)}
              }
          ],
          "steps": [
              [
                  {
                      "label": "$testLabelName",
                      "direction": "out",
                      "offset": 0,
                      "limit": 10
                  }
              ],
              [
                  {
                      "label": "$testLabelName",
                      "direction": "out",
                      "offset": 0,
                      "limit": 10
                  }
              ]
          ]
      }
       """.stripMargin

          val acts = route(FakeRequest(POST, "/graphs/getEdgesGroupedExcludedFormatted").withJsonBody(Json.parse(simpleQuery))).get

          //    logger.debug(s">> Social Controller test Acts result : ${contentAsJson(acts)}")
          status(acts) must equalTo(OK)
          contentType(acts) must beSome.which(_ == "text/plain")
          val jsRslt = contentAsJson(acts)
          println("======")
          println(jsRslt)
          println("======")
          jsRslt.as[JsObject].keys.contains("size") must equalTo(true)
          jsRslt.as[JsObject].keys.contains("results") must equalTo(true)
          (jsRslt \ "size").as[Int] must greaterThan(0)
          (jsRslt \ "size").as[Int] must equalTo(secondDepthVertexIds.length)
          ((jsRslt \ "results") \\ "name").seq(0).as[String] must equalTo("user_id")
          ((jsRslt \ "results") \\ "scoreSum").seq(0).as[Double] must equalTo(2.0f)
          (((jsRslt \ "results") \\ "aggr").seq(0).as[JsObject] \ "ids").as[JsArray].value.map(_.as[String]).toList should containAllOf(partialVertexIds.map(_.toString).toSeq)
        }

        "[getEdges query] test" in new WithApplication {
          val query =
            s"""
      {
          "srcVertices": [
              {
                  "serviceName": "$testServiceName",
                  "columnName": "$testColumnName",
                  "id": ${fromVertexIds(0)}
              }
          ],
          "steps": [
              [
                  {
                      "label": "$testLabelName",
                      "direction": "out",
                      "offset": 0,
                      "limit": 10
                  }
              ]
          ]
      }
       """.stripMargin

          val acts = route(FakeRequest(POST, "/graphs/getEdges").withJsonBody(Json.parse(query))).get

          //    logger.debug(s">> Social Controller test Acts result : ${contentAsJson(acts)}")
          status(acts) must equalTo(OK)
          contentType(acts) must beSome.which(_ == "text/plain")
          val jsRslt = contentAsJson(acts)
          println("======")
          println(jsRslt)
          println("======")

          jsRslt.as[JsObject].keys.contains("size") must equalTo(true)
          jsRslt.as[JsObject].keys.contains("results") must equalTo(true)
          (jsRslt \ "size").as[Int] must greaterThan(0)
          (jsRslt \ "size").as[Int] must equalTo(toVertexIds.length)
          ((jsRslt \ "results") \\ "from").seq(0).toString must equalTo(s"${fromVertexIds(0)}")
        }
      }

    }

}

abstract class QuerySpecificationBase extends Specification {
  protected val testServiceName = "s2graph_test"
  protected val testLabelName = "s2graph_label_test"
  protected val testColumnName = "user_id"

  val createService =
    s"""
      |{
      | "serviceName" : "$testServiceName"
      |}
    """.stripMargin

  val createLabel =
    s"""
      |{
      | "label": "$testLabelName",
      | "srcServiceName": "$testServiceName",
      | "srcColumnName": "$testColumnName",
      | "srcColumnType": "long",
      | "tgtServiceName": "$testServiceName",
      | "tgtColumnName": "$testColumnName",
      | "tgtColumnType": "long",
      | "indexProps": {
      |   "time": 0,
      |   "weight":0
      | }
      |}
    """.stripMargin

  // Generate sample vertex ids
  //val fromVertexIds = Array(1, 2, 3, 4, 5)
  val fromVertexIds = Array(1, 2)
  val toVertexIds = Array(10, 20, 30, 40, 50)
  // select some ids from vertice ids and add new ids
  val partialVertexIds = toVertexIds.partition(_ % 20 == 0)._1

  val secondDepthVertexIds = Array(100, 200, 300, 400)

  /**
   * Generate all combinations between from and to
   */
  def edgesInsertInitial() = {
    var idx = 0
    for {
      start <- fromVertexIds
      to <- toVertexIds
    } yield {
      idx += 1
      val curTime = System.currentTimeMillis + idx
      s"""
        |{
        | "from":$start,
        | "to":$to,
        | "label":"$testLabelName",
        | "timestamp":$curTime,
        | "props": {"time":$curTime, "weight":100}
        |}
      """.stripMargin
    }
  }

  /**
   * Generate all combinations between to and secondDepth
   */
  def edgesInsert2ndDepth() = {
    var idx = 0
    for {
      start <- partialVertexIds
      to <- secondDepthVertexIds
    } yield {
      idx += 1
      Thread.sleep(1)
      val curTime = System.currentTimeMillis + idx
      s"""
        |{
        | "from":$start,
        | "to":$to,
        | "label":"$testLabelName",
        | "timestamp":$curTime,
        | "props": {"time":$curTime, "weight":100}
        |}
      """.stripMargin
    }
  }

  def initialize = {
    running(FakeApplication()) {
      GraphAggregatorActor.init()
      KafkaAggregatorActor.init()
      Graph(Config.conf)(ExecutionContext.Implicits.global)

      // 1. createService
      var result = AdminController.createServiceInner(Json.parse(createService))
      println(s">> Service created : $createService, $result")
      // 2. createLabel
      result = AdminController.createLabelInner(Json.parse(createLabel))
      println(s">> Label created : $createLabel, $result")
      
      // 3. insert edges
      val jsArrStr = s"[${edgesInsertInitial.mkString(",")}]"
      println(s">> 1st step Inserts : $jsArrStr")
      val inserts = toEdges(Json.parse(jsArrStr), "insert")
      Graph.mutateEdges(inserts)
      println(s"<< 1st step Inserted : $jsArrStr")

      val jsArrStr2nd = s"[${edgesInsert2ndDepth.mkString(",")}]"
      println(s">> 2nd step Inserts : $jsArrStr2nd")
      val inserts2nd = toEdges(Json.parse(jsArrStr2nd), "insert")
      Graph.mutateEdges(inserts2nd)
      println(s"<< 2nd step Inserted : $inserts2nd")
    }
  }

  def cleanup = {
    running(FakeApplication()) {

      Graph(Config.conf)(ExecutionContext.Implicits.global)

      // 1. delete edges
      val jsArrStr = s"[${edgesInsertInitial.mkString(",")}]"
      println(s"Deletes : $jsArrStr")
      val deletes = toEdges(Json.parse(jsArrStr), "delete")
      Graph.mutateEdges(deletes)

      val jsArrStr2nd = s"[${edgesInsert2ndDepth.mkString(",")}]"
      println(s">> 2nd step Deletes : $jsArrStr2nd")
      val deletes2nd = toEdges(Json.parse(jsArrStr2nd), "delete")
      Graph.mutateEdges(deletes2nd)
      println(s"<< 2nd step Deleted : $deletes2nd")

      // 2. delete label ( currently NOT supported )
//      var result = AdminController.deleteLabelInner(testLabelName)
//      println(s">> Label deleted : $testLabelName, $result")
      // 3. delete service ( currently NOT supported )
      GraphAggregatorActor.shutdown()
      KafkaAggregatorActor.shutdown()
    }

  }

  //Do setup work here
  step {
    println("==== [QuerySpecificationBase] Doing setup work... ====")
    initialize
    success
  }

  //Include the real spec from the derived class
  include(spec)

  //Do shutdown work here
  step {
    println("===== [QuerySpecificationBase] Doing shutdown work... =====")
    cleanup
    success
  }

  /**
   * To be implemented in the derived class.  Returns the real specification
   * @return Specification
   */
  def spec: Specification
}
