package controllers

import io.prediction.commons.Config
import io.prediction.commons.settings._
import io.prediction.commons.modeldata.ItemRecScores
import io.prediction.commons.appdata.{ Users, Items, U2IActions }
import io.prediction.output.AlgoOutputSelector

import Helper.{ algoToJson, offlineEvalMetricToJson }
import Helper.{ dateTimeToString, algoParamToString, offlineEvalSplitterParamToString }
import Helper.{ getSimEvalStatus, getOfflineTuneStatus, createOfflineEval }

import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import play.api.data.format.Formats._
import play.api.data.validation.{ Constraints }
import play.api.i18n.{ Messages, Lang }
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.json.Json.toJson
import play.api.libs.json.{ JsNull, JsArray, Json, JsValue, Writes, JsObject }
import play.api.libs.ws.WS
import play.api.Play.current
import play.api.http

import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._
import scala.util.Random

import com.github.nscala_time.time.Imports._
import org.apache.commons.codec.digest.DigestUtils

import Forms._

/*
 * TODO:
 * - decodeURIComponent any GET custom param
 */

/*
 * Backend of ControlPanel.
 * Pure REST APIs in JSON.
 */
object Application extends Controller {
  /** PredictionIO Commons settings*/
  val config = new Config()
  val users = config.getSettingsUsers()
  val apps = config.getSettingsApps()
  val engines = config.getSettingsEngines()
  val engineInfos = config.getSettingsEngineInfos()
  val algos = config.getSettingsAlgos()
  val algoInfos = config.getSettingsAlgoInfos()
  val offlineEvalMetricInfos = config.getSettingsOfflineEvalMetricInfos()
  val offlineEvalSplitterInfos = config.getSettingsOfflineEvalSplitterInfos()
  val offlineEvals = config.getSettingsOfflineEvals()
  val offlineEvalMetrics = config.getSettingsOfflineEvalMetrics()
  val offlineEvalResults = config.getSettingsOfflineEvalResults()
  val offlineEvalSplitters = config.getSettingsOfflineEvalSplitters()
  val offlineTunes = config.getSettingsOfflineTunes()
  val paramGens = config.getSettingsParamGens()

  /** PredictionIO Commons modeldata */
  val itemRecScores = config.getModeldataItemRecScores()
  val itemSimScores = config.getModeldataItemSimScores()

  /** PredictionIO Commons modeldata */
  val trainingItemRecScores = config.getModeldataTrainingItemRecScores()
  val trainingItemSimScores = config.getModeldataTrainingItemSimScores()

  /** PredictionIO Commons appdata */
  val appDataUsers = config.getAppdataUsers()
  val appDataItems = config.getAppdataItems()
  val appDataU2IActions = config.getAppdataU2IActions()

  /** PredictionIO Commons training set appdata */
  val trainingSetUsers = config.getAppdataTrainingUsers()
  val trainingSetItems = config.getAppdataTrainingItems()
  val trainingSetU2IActions = config.getAppdataTrainingU2IActions()

  /** PredictionIO Commons validation set appdata */
  val validationSetUsers = config.getAppdataValidationUsers()
  val validationSetItems = config.getAppdataValidationItems()
  val validationSetU2IActions = config.getAppdataValidationU2IActions()

  /** PredictionIO Commons test set appdata */
  val testSetUsers = config.getAppdataTestUsers()
  val testSetItems = config.getAppdataTestItems()
  val testSetU2IActions = config.getAppdataTestU2IActions()

  /** Scheduler setting */
  val settingsSchedulerUrl = config.settingsSchedulerUrl

  /** PredictionIO Output */
  val algoOutputSelector = new AlgoOutputSelector(algos)

  /** misc */
  val nameRegex = """\b[a-zA-Z][a-zA-Z0-9_-]*\b""".r

  /** Play Framework security */
  def username(request: RequestHeader) = request.session.get(Security.username)

  def onUnauthorized(request: RequestHeader) = Forbidden(toJson(Map("message" -> toJson("Haven't signed in yet."))))

  def withAuth(f: => String => Request[AnyContent] => Result) = {
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
  }

  def withAuthAsync(f: => String => Request[AnyContent] => Future[SimpleResult]) = {
    Security.Authenticated(username, onUnauthorized) { user =>
      Action.async(request => f(user)(request))
    }
  }

  object WithUser {
    def apply(f: User => Request[AnyContent] => SimpleResult) = async { user =>
      implicit request =>
        Future.successful(f(user)(request))
    }

    def async(f: User => Request[AnyContent] => Future[SimpleResult]) = withAuthAsync { username =>
      implicit request =>
        users.getByEmail(username).map { user =>
          f(user)(request)
        }.getOrElse(Future.successful(onUnauthorized(request)))
    }
  }

  object WithApp {
    def apply(appid: Int)(f: (User, App) => Request[AnyContent] => SimpleResult) = async(appid) { (user, app) =>
      implicit request =>
        Future.successful(f(user, app)(request))
    }

    def async(appid: Int)(f: (User, App) => Request[AnyContent] => Future[SimpleResult]) = WithUser.async { user =>
      implicit request =>
        apps.getByIdAndUserid(appid, user.id).map { app =>
          f(user, app)(request)
        }.getOrElse(Future.successful(NotFound(Json.obj("message" -> s"Invalid appid ${appid}."))))
    }
  }

  object WithEngine {
    def apply(appid: Int, engineid: Int)(f: (User, App, Engine) => Request[AnyContent] => SimpleResult) = async(appid, engineid) {
      (user, app, eng) =>
        implicit request =>
          Future.successful(f(user, app, eng)(request))
    }

    def async(appid: Int, engineid: Int)(f: (User, App, Engine) => Request[AnyContent] => Future[SimpleResult]) = WithApp.async(appid) {
      (user, app) =>
        implicit request =>
          engines.getByIdAndAppid(engineid, appid).map { eng =>
            f(user, app, eng)(request)
          }.getOrElse(Future.successful(NotFound(Json.obj("message" -> s"Invalid engineid ${engineid}."))))
    }
  }

  object WithAlgo {
    def apply(appid: Int, engineid: Int, algoid: Int)(f: (User, App, Engine, Algo) => Request[AnyContent] => SimpleResult) = async(appid, engineid, algoid) {
      (user, app, eng, algo) =>
        implicit request =>
          Future.successful(f(user, app, eng, algo)(request))
    }

    def async(appid: Int, engineid: Int, algoid: Int)(f: (User, App, Engine, Algo) => Request[AnyContent] => Future[SimpleResult]) = WithEngine.async(appid, engineid) {
      (user, app, eng) =>
        implicit request =>
          algos.getByIdAndEngineid(algoid, engineid).map { algo =>
            f(user, app, eng, algo)(request)
          }.getOrElse(Future.successful(NotFound(Json.obj("message" -> s"Invalid algoid ${algoid}."))))
    }
  }

  object WithOfflineEval {
    def apply(appid: Int, engineid: Int, offlineevalid: Int)(f: (User, App, Engine, OfflineEval) => Request[AnyContent] => SimpleResult) = async(appid, engineid, offlineevalid) {
      (user, app, eng, eval) =>
        implicit request =>
          Future.successful(f(user, app, eng, eval)(request))
    }

    def async(appid: Int, engineid: Int, offlineevalid: Int)(f: (User, App, Engine, OfflineEval) => Request[AnyContent] => Future[SimpleResult]) = WithEngine.async(appid, engineid) {
      (user, app, eng) =>
        implicit request =>
          offlineEvals.getByIdAndEngineid(offlineevalid, engineid).map { eval =>
            f(user, app, eng, eval)(request)
          }.getOrElse(Future.successful(NotFound(Json.obj("message" -> s"Invalid offlineevalid ${offlineevalid}."))))
    }
  }

  private def md5password(password: String) = DigestUtils.md5Hex(password)

  /** Appkey Generation */
  def randomAlphanumeric(n: Int): String = {
    Random.alphanumeric.take(n).mkString
  }

  def showWeb() = Action {
    Ok(views.html.Web.index())
  }

  /* Serve Engines/Algorithms Static Files (avoid PlayFramework's Assets cache problem during development)*/
  def enginebase(path: String) = Action {
    Ok.sendFile(new java.io.File(Play.application.path, "/enginebase/" + path))
    //TODO: Fix Content-Disposition
  }

  def redirectToWeb = Action {
    Redirect("web/")
  }

  /* case class to json conversion */
  implicit val userWrites = new Writes[User] {
    /* note: do not return password */
    def writes(u: User): JsValue = {
      Json.obj(
        "id" -> u.id,
        "username" -> (u.firstName + u.lastName.map(" " + _).getOrElse("")),
        "email" -> u.email
      )
    }
  }

  /**
   * Authenticates user
   *
   * {{{
   * POST
   * JSON parameters:
   *   {
   *     "email" : <string>,
   *     "password" : <string>,
   *     "remember" : <optional string "on">
   *   }
   * JSON response:
   *   {
   *     "id" : <string>,
   *     "username" : <string>,
   *     "email" : <string>
   *   }
   * }}}
   *
   */
  def signin = Action { implicit request =>
    val loginForm = Form(
      tuple(
        "email" -> text,
        "password" -> text,
        "remember" -> optional(text)
      ) verifying ("Invalid email or password", result => result match {
          case (email, password, remember) => users.authenticateByEmail(email, md5password(password)) map { _ => true } getOrElse false
        })
    )

    loginForm.bindFromRequest.fold(
      formWithErrors => Forbidden(toJson(Map("message" -> toJson("Incorrect Email or Password.")))),
      form => {
        users.getByEmail(form._1).map(user =>
          Ok(Json.toJson(user)).withSession(Security.username -> user.email)
        ).getOrElse(
          InternalServerError(Json.obj("message" -> "Could not find your user account."))
        )
      }
    )
  }

  /**
   * Signs out
   *
   * {{{
   * POST
   * JSON parameters:
   *   None
   * JSON response:
   *   None
   * }}}
   */
  def signout = Action {
    Ok.withNewSession
  }

  /**
   * Returns authenticated user info
   * (from session cookie)
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If authenticated
   *   OK
   *   {
   *     "id" : <string>,
   *     "username" : <string>,
   *     "email": <string>
   *   }
   *
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   * }}}
   */
  def getAuth = WithUser { user =>
    implicit request =>
      Ok(Json.toJson(user))
  }

  /**
   * Returns list of apps of the authenticated user
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If no app:
   *   No Content
   *
   *   If apps are found:
   *   OK
   *   [ { "id" : <appid int>,  "appname" : <string> },
   *     ...
   *   ]
   *
   * }}}
   */
  def getApplist = WithUser { user =>
    implicit request =>

      val userApps = apps.getByUserid(user.id)
      if (!userApps.hasNext) NoContent
      else {
        Ok(JsArray(userApps.map { app =>
          Json.obj("id" -> app.id, "appname" -> app.display)
        }.toSeq))
      }
  }

  /**
   * Returns the app details of this appid
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If app is not found:
   *   NotFound
   *   {
   *     "message" : "Invalid appid."
   *   }
   *
   *   If app is found:
   *   Ok
   *   {
   *     "id" : <appid int>,
   *     "updatedtime" : <string>,
   *     "userscount": <num of users int>
   *     "itemscount": <num of items int>
   *     "u2icount": <num of u2i Actions int>
   *     "apiurl": <url of API server, string>
   *     "appkey": <string>
   *   }
   * }}}
   *
   * @param id the App ID
   */
  def getAppDetails(id: Int) = WithApp(id) { (user, app) =>
    implicit request =>
      val numUsers = appDataUsers.countByAppid(app.id)
      val numItems = appDataItems.countByAppid(app.id)
      val numU2IActions = appDataU2IActions.countByAppid(app.id)
      Ok(Json.obj(
        "id" -> app.id,
        "updatedtime" -> dateTimeToString(DateTime.now),
        "userscount" -> numUsers,
        "itemscount" -> numItems,
        "u2icount" -> numU2IActions,
        "apiurl" -> "http://yourhost.com:123/appid12",
        "appkey" -> app.appkey
      ))
  }

  /**
   * Returns an app
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If app is found:
   *   Ok
   *   {
   *     "id" : <appid int>
   *     "appname" : <string>
   *   }
   *
   * }}}
   *
   * @param id the App ID
   */
  def getApp(id: Int) = WithApp(id) { (user, app) =>
    implicit request =>
      Ok(Json.obj(
        "id" -> app.id,
        "appname" -> app.display
      ))
  }

  /**
   * Create an app
   *
   * {{{
   * POST
   * JSON Parameters:
   *   {
   *     "appname" : <the new app name. string>
   *   }
   * JSON Response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If creation failed:
   *   BadRequest
   *   {
   *     "message" : "Invalid character for app name."
   *    }
   *
   *   If app is created:
   *   OK
   *   {
   *     "id" : <the appid of the created app. int>,
   *     "appname" : <string>
   *   }
   * }}}
   *
   */
  def createApp = WithUser { user =>
    implicit request =>

      val appForm = Form(single(
        "appname" -> nonEmptyText
      ))

      appForm.bindFromRequest.fold(
        formWithError => {
          val msg = formWithError.errors(0).message // extract 1st error message only
          BadRequest(toJson(Map("message" -> toJson(msg))))
        },
        formData => {
          val an = formData
          val appid = apps.insert(App(
            id = 0,
            userid = user.id,
            appkey = randomAlphanumeric(64),
            display = an,
            url = None,
            cat = None,
            desc = None,
            timezone = "UTC"
          ))
          Logger.info("Create app ID " + appid)

          Ok(Json.obj(
            "id" -> appid,
            "appname" -> an
          ))
        }
      )
  }

  /**
   * Remove an app
   *
   * {{{
   * DELETE
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If not found:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If error:
   *   InternalServerError
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If deleted successfully:
   *   Ok
   * }}}
   *
   * @param id the App ID
   */
  def removeApp(id: Int) = WithApp.async(id) { (user, app) =>
    implicit request =>

      // don't delete if there is any deployed aglo, sim eval or offline tune pending
      val appEngines = engines.getByAppid(app.id).toList

      val enginesDeployed = appEngines.filter(eng =>
        !(algos.getDeployedByEngineid(eng.id).isEmpty)
      )
      val msgDeployed = "There are deployed algorithms in engines: " + enginesDeployed.map(_.name).mkString(", ") + ". Please undeploy them before delete this app."

      val enginesSimEvals = appEngines.filter(eng =>
        !(Helper.getSimEvalsByEngineid(eng.id).filter(Helper.isPendingSimEval(_)).isEmpty)
      )
      val msgSimEvals = "There are running simulated evaluations in engines: " + enginesSimEvals.map(_.name).mkString(", ") + ". Please stop and delete them before delete this app."

      val enginesOfflineTunes = appEngines.filter(eng =>
        !(offlineTunes.getByEngineid(eng.id).filter(Helper.isPendingOfflineTune(_)).isEmpty)
      )
      val msgOfflineTunes = "There are auto-tuning algorithms in engines: " + enginesOfflineTunes.map(_.name).mkString(", ") + ". Please stop and delete them before delete this app."

      val runningEngines = List(
        (enginesDeployed, msgDeployed),
        (enginesSimEvals, msgSimEvals),
        (enginesOfflineTunes, msgOfflineTunes)
      ).filter { case (x, y) => (!x.isEmpty) }

      if (!runningEngines.isEmpty) {
        val msg = runningEngines.map { case (x, y) => y }.mkString(" ")
        concurrent.Future(Forbidden(Json.obj("message" -> msg)))
      } else {

        val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))
        val delete = Helper.deleteAppScheduler(app.id)

        concurrent.Future.firstCompletedOf(Seq(delete, timeout)).map {
          case r: SimpleResult => {
            if (r.header.status == http.Status.OK) {
              Helper.deleteApp(id, user.id, keepSettings = false)
            }
            r
          }
          case t: String => InternalServerError(Json.obj("message" -> t))
        }
      }
  }

  /**
   * Erase appdata of this appid
   *
   * {{{
   * POST
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If erased successfully:
   *   Ok
   * }}}
   *
   * @param id the App ID
   */
  def eraseAppData(id: Int) = WithApp.async(id) { (user, app) =>
    implicit request =>

      val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))
      val delete = Helper.deleteAppScheduler(app.id)

      concurrent.Future.firstCompletedOf(Seq(delete, timeout)).map {
        case r: SimpleResult => {
          if (r.header.status == http.Status.OK) {
            Helper.deleteApp(id, user.id, keepSettings = true)
          }
          r
        }
        case t: String => InternalServerError(Json.obj("message" -> t))
      }
  }

  /**
   * Returns a list of available engine infos in the system
   *
   * {{{
   * GET
   * JSON Parameters:
   *   None
   * JSON Response:
   *   Ok
   *   [ { "id" : <engine info id stirng>,
   *       "engineinfoname" : <name of the engine info>,
   *       "description": <description in html string>
   *     },
   *     ...
   *   ]
   * }}}
   */
  def getEngineInfoList = Action {
    Ok(JsArray(engineInfos.getAll() map {
      eng =>
        Json.obj(
          "id" -> eng.id,
          "engineinfoname" -> eng.name,
          "description" -> eng.description
        )
    }))
  }

  /**
   * Returns a list of available algo infos of a specific engine info
   *
   * {{{
   * GET
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If the engine info id is not found:
   *   InternalServerError
   *   {
   *     "message" : "Invalid EngineInfo ID."
   *   }
   *
   *   If found:
   *   Ok
   *   { "engineinfoname" : <the name of the engine info>,
   *     "algotypelist" : [ { "id" : <algo info id>,
   *                          "algoinfoname" : <name of the algo info>,
   *                          "description" : <string>,
   *                          "req" : [<technology requirement string>],
   *                          "datareq" : [<data requirement string>]
   *                        }, ...
   *                      ]
   *   }
   * }}}
   *
   * @param id the engine info id
   */
  def getEngineInfoAlgoInfoList(id: String) = Action {
    engineInfos.get(id) map { engineInfo =>
      Ok(Json.obj(
        "engineinfoname" -> engineInfo.name,
        "algotypelist" -> JsArray(
          algoInfos.getByEngineInfoId(id).map { algoInfo =>
            Json.obj(
              "id" -> algoInfo.id,
              "algoinfoname" -> algoInfo.name,
              "description" -> algoInfo.description.getOrElse[String](""),
              "req" -> Json.toJson(algoInfo.techreq),
              "datareq" -> Json.toJson(algoInfo.datareq)
            )
          }
        )
      ))
    } getOrElse InternalServerError(Json.obj("message" -> s"Invalid EngineInfo ID: ${id}."))
  }

  /**
   * Returns a list of available metric infos of a specific engine info
   *
   * {{{
   * GET
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If the engine info id is not found:
   *   InternalServerError
   *   {
   *     "message" : "Invalid EngineInfo ID."
   *   }
   *
   *   If found:
   *   Ok
   *   { "engineinfoname" : <the name of the engine info>,
   *     "defaultmetric" : <default metric info id>,
   *     "metricslist" : [ { "id" : <metric info id>,
   *                         "name" : <short name of the metric info>,
   *                         "description" : <long name of the metric info>,
   *                       }, ...
   *                     ]
   *   }
   * }}}
   *
   * @param id the engine info id
   */
  def getEngineInfoMetricInfoList(id: String) = Action {
    engineInfos.get(id) map { engInfo =>
      val metrics = offlineEvalMetricInfos.getByEngineinfoid(engInfo.id).map { m =>
        Json.obj(
          "id" -> m.id,
          "name" -> m.name,
          "description" -> m.description
        )
      }
      Ok(Json.obj(
        "engineinfoname" -> engInfo.name,
        "defaultmetric" -> engInfo.defaultofflineevalmetricinfoid,
        "metricslist" -> JsArray(metrics)
      ))
    } getOrElse {
      InternalServerError(Json.obj("message" -> s"Invalid engineinfo ID: ${id}."))
    }
  }

  /**
   * Returns a list of available splitter infos of a specific engine info
   *
   * {{{
   * GET
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If the engine info id is not found:
   *   InternalServerError
   *   {
   *     "message" : "Invalid EngineInfo ID."
   *   }
   *
   *   If found:
   *   Ok
   *   { "engineinfoname" : <the name of the engine info>,
   *     "defaultsplitter": <default splitter info id>,
   *     "splitterlist" : [ { "id" : <splitter info id>,
   *                          "name" : <name of splitter>,
   *                          "description" : <splitter description>,
   *                       }, ...
   *                     ]
   *   }
   * }}}
   *
   * @param id the engine info id
   */
  def getEngineInfoSplitterInfoList(id: String) = Action {
    engineInfos.get(id).map { engInfo =>
      val splitters = offlineEvalSplitterInfos.getByEngineinfoid(engInfo.id).map { m =>
        Json.obj(
          "id" -> m.id,
          "name" -> m.name,
          "description" -> m.description
        )
      }
      Ok(Json.obj(
        "engineinfoname" -> engInfo.name,
        "defaultsplitter" -> engInfo.defaultofflineevalsplitterinfoid,
        "splitterlist" -> JsArray(splitters)
      ))
    }.getOrElse {
      InternalServerError(Json.obj("message" -> s"Invalid engineinfo ID: ${id}."))
    }
  }

  /**
   * Returns list of engines of this appid
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If no engine:
   *   NoContent
   *
   *   If engines found:
   *   Ok
   *   {
   *     "id" : <appid int>,
   *     "enginelist" : [ { "id" : <engineid int>, "enginename" : <string>, "engineinfoid" : <string> },
   *                       ....,
   *                      { "id" : <engineid int>, "enginename" : <string>, "engineinfoid" : <string> } ]
   *
   *   }
   * }}}
   *
   * @param id the App ID
   */
  def getAppEnginelist(appid: Int) = WithApp(appid) { (user, app) =>
    implicit request =>

      val appEngines = engines.getByAppid(appid)

      if (!appEngines.hasNext) NoContent
      else
        Ok(Json.obj(
          "id" -> appid,
          "enginelist" -> JsArray(appEngines.map { eng =>
            Json.obj("id" -> eng.id, "enginename" -> eng.name, "engineinfoid" -> eng.infoid)
          }.toSeq)
        ))
  }

  /**
   * Returns the engine of this engineid
   *
   * {{{
   * GET
   * JSON Parameters:
   *   None
   * JSON Response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If engine not found:
   *   NotFound
   *   {
   *     "message" : "Invalid app id or engine id."
   *   }
   *
   *   If engine found:
   *   Ok
   *   {
   *     "id" : <engine id>,
   *     "engineinfoid" : <engine info id>,
   *     "enginename" : <engine name>,
   *     "enginestatus" : <engine status>
   *   }
   * }}}
   * @note engine status:
   *   noappdata
   *   nodeployedalgo
   *   firsttraining
   *   nomodeldata
   *   nomodeldatanoscheduler
   *   training
   *   running
   *   runningnoscheduler
   *
   * @param appid the App ID
   * @param id the engine ID
   */
  def getEngine(appid: Int, id: Int) = WithEngine(appid, id) { (user, app, eng) =>
    implicit request =>

      val modelDataExist: Boolean = eng.infoid match {
        case "itemrec" => try { itemRecScores.existByAlgo(algoOutputSelector.itemRecAlgoSelection(eng)) } catch { case e: RuntimeException => false }
        case "itemsim" => try { itemSimScores.existByAlgo(algoOutputSelector.itemSimAlgoSelection(eng)) } catch { case e: RuntimeException => false }
        case _ => false
      }
      val deployedAlgos = algos.getDeployedByEngineid(eng.id)
      val hasDeployedAlgo = deployedAlgos.hasNext
      val algo = if (deployedAlgos.hasNext) Some(deployedAlgos.next()) else None
      val engineStatus: String =
        if (appDataUsers.countByAppid(eng.appid) == 0 && appDataItems.countByAppid(eng.appid) == 0 && appDataU2IActions.countByAppid(eng.appid) == 0)
          "noappdata"
        else if (!hasDeployedAlgo)
          "nodeployedalgo"
        else if (!modelDataExist)
          try {
            (Await.result(WS.url(s"${settingsSchedulerUrl}/apps/${eng.appid}/engines/${eng.id}/algos/${algo.get.id}/status").get(), scala.concurrent.duration.Duration(5, SECONDS)).json \ "status").as[String] match {
              case "jobrunning" => "firsttraining"
              case _ => "nomodeldata"
            }
          } catch {
            case e: java.net.ConnectException => "nomodeldatanoscheduler"
          }
        else
          try {
            (Await.result(WS.url(s"${settingsSchedulerUrl}/apps/${eng.appid}/engines/${eng.id}/algos/${algo.get.id}/status").get(), scala.concurrent.duration.Duration(5, SECONDS)).json \ "status").as[String] match {
              case "jobrunning" => "training"
              case _ => "running"
            }
          } catch {
            case e: java.net.ConnectException => "runningnoscheduler"
          }
      Ok(Json.obj(
        "id" -> eng.id, // engine id
        "engineinfoid" -> eng.infoid,
        "appid" -> eng.appid,
        "enginename" -> eng.name,
        "enginestatus" -> engineStatus))
  }

  /**
   * Creates an Engine
   *
   * {{{
   * POST
   * JSON parameters:
   *   {
   *     "engineinfoid" : <engine info id>,
   *     "enginename" : <engine name>
   *   }
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   if invalid appid:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If bad param:
   *   BadRequest
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If created:
   *   Ok
   *   {
   *     "id" : <new engine id>,
   *     "engineinfoid" : <engine info id>,
   *     "appid" : <app id>,
   *     "enginename" : <engine name>
   *   }
   *
   * }}}
   *
   * @param appid the App ID
   */
  def createEngine(appid: Int) = WithApp(appid) { (user, app) =>
    implicit request =>

      val supportedEngineTypes: Seq[String] = engineInfos.getAll() map { _.id }
      val enginenameConstraint = Constraints.pattern(nameRegex, "constraint.enginename", "Engine names should only contain alphanumerical characters, underscores, or dashes. The first character must be an alphabet.")

      val engineForm = Form(tuple(
        "engineinfoid" -> (text verifying ("This feature will be available soon.", e => supportedEngineTypes.contains(e))),
        "enginename" -> (text verifying ("Please name your engine.", enginename => enginename.length > 0)
          verifying enginenameConstraint)
      ) verifying ("Engine name must be unique.", f => !engines.existsByAppidAndName(appid, f._2))
        verifying ("Engine type is invalid.", f => engineInfos.get(f._1).map(_ => true).getOrElse(false)))

      engineForm.bindFromRequest.fold(
        formWithError => {
          val msg = formWithError.errors(0).message // extract 1st error message only
          BadRequest(toJson(Map("message" -> toJson(msg))))
        },
        formData => {
          val (enginetype, enginename) = formData
          val engineInfo = engineInfos.get(enginetype).get
          val engineId = engines.insert(Engine(
            id = -1,
            appid = appid,
            name = enginename,
            infoid = enginetype,
            itypes = None, // NOTE: default None (means all itypes)
            params = engineInfo.params.map(s => (s._2.id, s._2.defaultvalue))
          ))
          Logger.info("Create engine ID " + engineId)

          // automatically create default algo
          val defaultAlgoType = engineInfo.defaultalgoinfoid
          val params = algoInfos.get(defaultAlgoType).get.params.mapValues(_.defaultvalue)

          val defaultAlgo = Algo(
            id = -1,
            engineid = engineId,
            name = "Default-Algo",
            infoid = defaultAlgoType,
            command = "",
            params = params,
            settings = Map(), // no use for now
            modelset = false, // init value
            createtime = DateTime.now,
            updatetime = DateTime.now,
            status = "deployed", // this is default deployed algo
            offlineevalid = None,
            loop = None
          )

          val algoId = algos.insert(defaultAlgo)
          Logger.info("Create algo ID " + algoId)

          WS.url(settingsSchedulerUrl + "/users/" + user.id + "/sync").get()

          Ok(Json.obj(
            "id" -> engineId, // engine id
            "engineinfoid" -> enginetype,
            "appid" -> appid,
            "enginename" -> enginename))
        }
      )

  }

  /**
   * Removes an engine
   *
   * {{{
   * DELETE
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If deleted:
   *   Ok
   *
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def removeEngine(appid: Int, engineid: Int) = WithEngine.async(appid, engineid) { (user, app, eng) =>
    implicit request =>
      // don't delete if there is any sim eval and offline tune pending, or deployed algorithm
      val pendingSimEvals = Helper.getSimEvalsByEngineid(eng.id).filter(x => Helper.isPendingSimEval(x)).toList
      val pendingOfflineTunes = offlineTunes.getByEngineid(eng.id).filter(x => Helper.isPendingOfflineTune(x)).toList
      val deployedAlgos = algos.getDeployedByEngineid(eng.id).toList

      if (deployedAlgos.size != 0) {
        val names = deployedAlgos map (x => x.name) mkString (",")
        Future.successful(Forbidden(Json.obj("message" -> s"This engine has deployed algorithms (${names}). Please undeploy them before delete this engine.")))
      } else if (pendingSimEvals.size != 0) {
        Future.successful(Forbidden(Json.obj("message" -> "There are running simulated evaluations. Please stop and delete them before delete this engine.")))
      } else if (pendingOfflineTunes.size != 0) {
        Future.successful(Forbidden(Json.obj("message" -> "There are auto-tuning algorithms. Please stop and delete them before delete this engine.")))
      } else {
        /** Deletion could take a while */
        val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))

        // to scheduler: delete engine
        val delete = Helper.deleteEngineScheduler(appid, engineid)

        concurrent.Future.firstCompletedOf(Seq(delete, timeout)).map {
          case r: SimpleResult => {
            if (r.header.status == http.Status.OK) {
              Helper.deleteEngine(engineid, appid, keepSettings = false)
            }
            r
          }
          case t: String => InternalServerError(Json.obj("message" -> t))
        }
      }
  }

  /**
   * Returns a list of available (added but not deployed) algorithms of this engine
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If no algo:
   *   NoContent
   *
   *   If algos found:
   *   [ { see algoToJson
   *     }, ...
   *   ]
   * }}}
   * @note algo status
   *   TODO: add more info here...
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def getAvailableAlgoList(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>

      val engineAlgos = algos.getByEngineid(engineid).filter { Helper.isAvailableAlgo(_) }

      if (!engineAlgos.hasNext) NoContent
      else
        Ok(Json.toJson( // NOTE: only display algos which are not "deployed", nor "simeval"
          engineAlgos.map { algo =>
            val algoInfo = algoInfos.get(algo.infoid)
            algoToJson(algo, appid, algoInfo)
          }.toSeq
        ))
  }

  /**
   * Returns an available algorithm
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If algo not found:
   *   NotFound
   *   {
   *     "message" : "Invalid app id, engine id or algo id."
   *   }
   *
   *   If found:
   *   Ok
   *   {
   *     see algoToJson
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param id the algo ID
   */
  def getAvailableAlgo(appid: Int, engineid: Int, id: Int) = WithAlgo(appid, engineid, id) { (user, app, eng, algo) =>
    implicit request =>
      algoInfos.get(algo.infoid).map { info =>
        Ok(algoToJson(algo, appid, Some(info)))
      }.getOrElse {
        InternalServerError(Json.obj("message" -> s"Algoinfo ${algo.infoid} not found."))
      }
  }

  /**
   * Creates an new algorithm
   * {{{
   * POST
   * JSON parameters:
   *   {
   *     "algoinfoid" : <algo info id>,
   *     "algoname" : <algo name>,
   *   }
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If invalid appid or engineid:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If creation failed:
   *   BadRequest
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If created:
   *   Ok
   *   {
   *     see algoToJson
   *   }
   *
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def createAvailableAlgo(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>

      val supportedAlgoTypes: Seq[String] = algoInfos.getAll map { _.id }
      val algonameConstraint = Constraints.pattern(nameRegex, "constraint.algoname", "Algorithm names should only contain alphanumerical characters, underscores, or dashes. The first character must be an alphabet.")

      val createAlgoForm = Form(tuple(
        "algoinfoid" -> (nonEmptyText verifying ("This feature will be available soon.", t => supportedAlgoTypes.contains(t))),
        "algoname" -> (text verifying ("Please name your algo.", name => name.length > 0)
          verifying algonameConstraint) // same name constraint as engine
      ) verifying ("Algo name must be unique.", f => !algos.existsByEngineidAndName(engineid, f._2)))

      createAlgoForm.bindFromRequest.fold(
        formWithError => {
          val msg = formWithError.errors(0).message // extract 1st error message only
          BadRequest(toJson(Map("message" -> toJson(msg))))
        },
        formData => {
          val (algoType, algoName) = formData

          algoInfos.get(algoType).map { algoInfo =>

            val newAlgo = Algo(
              id = -1,
              engineid = engineid,
              name = algoName,
              infoid = algoType,
              command = "",
              params = algoInfo.params.mapValues(_.defaultvalue),
              settings = Map(), // no use for now
              modelset = false, // init value
              createtime = DateTime.now,
              updatetime = DateTime.now,
              status = "ready", // default status
              offlineevalid = None,
              loop = None
            )

            val algoId = algos.insert(newAlgo)
            Logger.info("Create algo ID " + algoId)

            Ok(algoToJson(newAlgo.copy(id = algoId), appid, Some(algoInfo)))
          }.getOrElse {
            InternalServerError(Json.obj("message" -> s"Algoinfo ${algoType} not found."))
          }
        }
      )
  }

  /**
   * Deletes an algorithm
   * {{{
   * DELETE
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If deleted:
   *   Ok
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param id the algo ID
   */
  def removeAvailableAlgo(appid: Int, engineid: Int, id: Int) = WithAlgo.async(appid, engineid, id) { (user, app, eng, algo) =>
    implicit request =>
      /** Deletion could take a while */
      val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))

      val deleteTune = algo.offlinetuneid map { tuneid =>
        offlineTunes.get(tuneid) map { tune =>
          /** Make sure to unset offline tune's creation time to prevent scheduler from picking up */
          offlineTunes.update(tune.copy(createtime = None))

          Helper.stopAndDeleteOfflineTuneScheduler(appid, engineid, tuneid)
        } getOrElse {
          concurrent.Future { Ok }
        }
      } getOrElse {
        concurrent.Future { Ok }
      }

      val deleteAlgo: concurrent.Future[SimpleResult] = Helper.deleteAlgoScheduler(appid, engineid, algo.id)

      val complete: concurrent.Future[SimpleResult] = concurrent.Future.reduce(Seq(deleteTune, deleteAlgo)) { (a, b) =>
        if (a.header.status != http.Status.OK) // keep the 1st error
          a
        else
          b
      }

      concurrent.Future.firstCompletedOf(Seq(complete, timeout)).map {
        case r: SimpleResult => {
          if (r.header.status == http.Status.OK) {
            algo.offlinetuneid map { tuneid =>
              Helper.deleteOfflineTune(tuneid, keepSettings = false)
            }
            Helper.deleteAlgo(algo.id, keepSettings = false)
          }
          r
        }
        case t: String => InternalServerError(Json.obj("message" -> t))
      }
  }

  /**
   * Returns a list of deployed algorithms
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON repseon:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If no deployed algo:
   *   NoContent
   *
   *   If deployed algos found:
   *   {
   *     "updatedtime" : <TODO>,
   *     "status" : <TODO>,
   *     "algolist" : [ { see algoToJson
   *                    }, ...
   *                  ]
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def getDeployedAlgoList(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>

      val deployedAlgos = algos.getDeployedByEngineid(engineid)

      if (!deployedAlgos.hasNext) NoContent
      else
        Ok(Json.obj(
          "updatedtime" -> "12-03-2012 12:32:12", // TODO: what's this time for?
          "status" -> "Running",
          "algolist" -> Json.toJson(deployedAlgos.map { algo =>
            val algoInfo = algoInfos.get(algo.infoid)
            algoToJson(algo, appid, algoInfo)
          }.toSeq)
        ))
  }

  /**
   * Deploys a list of algorithms (also undeploys any existing deployed algorithms)
   * The status of deployed algorithms change to "deployed"
   *
   * {{{
   * POST
   * JSON parameters:
   *   {
   *     "algoidlist" : [ array of algo ids ]
   *   }
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If any of the algo id is not valid:
   *   BadRequest
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If done:
   *   Ok
   *
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def algoDeploy(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>
      val deployForm = Form(
        "algoidlist" -> list(number)
      )
      deployForm.bindFromRequest.fold(
        formWithErrors => Ok,
        form => {
          val algoidList = form
          val algoList = algoidList.map(id => (id, algos.getByIdAndEngineid(id, engineid)))
          val invalidAlgos = algoList.filter {
            case (id, algoOpt) => algoOpt match {
              case None => true // not exist
              case Some(x) => (x.status != "ready") // not ready
            }
          }

          // make sure all algoids are valid
          if (!invalidAlgos.isEmpty) {
            val ids = invalidAlgos.map { case (id, algoOpt) => id }.mkString(", ")
            BadRequest(Json.obj("message" -> s"Invalid algo ids: ${ids}."))
          } else {
            algos.getDeployedByEngineid(engineid).foreach { algo =>
              algos.update(algo.copy(status = "ready"))
            }
            algoList.foreach {
              case (id, algoOpt) =>
                // algoOpt can't be None because of invalidAlgos check
                algos.update(algoOpt.get.copy(status = "deployed"))
            }
            WS.url(settingsSchedulerUrl + "/users/" + user.id + "/sync").get()
            Ok
          }
        }
      )
  }

  /**
   * Undeploys all deployed algorithms
   * {{{
   * POST
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If done:
   *   Ok
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def algoUndeploy(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>

      algos.getDeployedByEngineid(engineid) foreach { algo =>
        algos.update(algo.copy(status = "ready"))
      }
      WS.url(settingsSchedulerUrl + "/users/" + user.id + "/sync").get()
      Ok
  }

  /**
   * Requests to train model now
   * {{{
   * POST
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If error:
   *   InternalServerError
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If done:
   *   Ok
   *   {
   *     "message" : <message from scheduler>
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def algoTrainNow(appid: Int, engineid: Int) = WithEngine.async(appid, engineid) { (user, app, eng) =>
    implicit request =>
      // No extra param required
      val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))
      val request = WS.url(s"${settingsSchedulerUrl}/apps/${appid}/engines/${engineid}/trainoncenow").get() map { r =>
        Ok(Json.obj("message" -> (r.json \ "message").as[String]))
      } recover {
        case e: Exception => InternalServerError(Json.obj("message" -> e.getMessage()))
      }

      /** Detect timeout (10 minutes by default) */
      concurrent.Future.firstCompletedOf(Seq(request, timeout)).map {
        case r: SimpleResult => r
        case t: String => InternalServerError(Json.obj("message" -> t))
      }
  }

  /**
   * Returns a list of simulated evalulation for this engine
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If no sim evals:
   *   NoContent
   *
   *   If found:
   *   Ok
   *   [
   *     { "id" : <sim eval id>,
   *       "appid" : <app id>,
   *       "engineid" : <engine id>,
   *       "algolist" : [
   *                      { "id" : <algo id>,
   *                        "algoname" : <algo name>,
   *                        "appid" : <app id>,
   *                        "engineid" : <engine id>,
   *                        "algoinfoid" : <algo info id>,
   *                        "algoinfoname" : <algo info name>,
   *                        "settingsstring" : <algo setting string>
   *                      }, ...
   *                    ],
   *       "status" : <sim eval status>,
   *       "createtime" : <sim eval create time>,
   *       "endtime" : <sim eval end time>
   *     }, ...
   *   ]
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def getSimEvalList(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>

      // get offlineeval for this engine
      val engineOfflineEvals = Helper.getSimEvalsByEngineid(engineid)

      if (!engineOfflineEvals.hasNext) NoContent
      else {
        val resp = Json.toJson(

          engineOfflineEvals.map { eval =>

            val algolist = Json.toJson(
              algos.getByOfflineEvalid(eval.id).map { algo =>
                val algoInfo = algoInfos.get(algo.infoid)
                algoToJson(algo, appid, algoInfo, withParam = true)
              }.toSeq
            )

            val createtime = eval.createtime.map(dateTimeToString(_)).getOrElse("-")
            val starttime = eval.starttime.map(dateTimeToString(_)).getOrElse("-")
            val endtime = eval.endtime.map(dateTimeToString(_)).getOrElse("-")

            Json.obj(
              "id" -> eval.id,
              "appid" -> appid,
              "engineid" -> eval.engineid,
              "algolist" -> algolist,
              "status" -> getSimEvalStatus(eval),
              "createtime" -> createtime, // NOTE: use createtime here for test date
              "endtime" -> endtime
            )
          }.toSeq
        )
        Ok(resp)
      }
  }

  /**
   * Creates a simulated evalution
   *
   * {{{
   * POST
   * JSON parameters:
   *
   *  {
   *    "infoid[i]": <metric or splitter info id>
   *    "infotype[i]": <"offlineevalmetric" or "offlineevalsplitter">
   *    "other param [i]": <the parameter value for corresponding infoid[i]>
   *    "algo" : <list of algo ids to be evaluated>
   *    "splittrain": <training set split percentage 1 to 100>,
   *    "splittest": <test set split percentage 1 to 100>,
   *    "evaliteration": <number of iterations>
   *  }
   *
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If error:
   *   BadRequest
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If created:
   *   Ok
   *
   * }}}
   * @param appid the App ID
   * @param engineid the engine ID
   */
  def createSimEval(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, eng) =>
    implicit request =>
      val simEvalForm = Form(tuple(
        "infoid" -> seqOfMapOfStringToAny,
        "algoids" -> list(number), // algo id
        "splittrain" -> number(1, 100),
        "splittest" -> number(1, 100),
        "evaliteration" -> (number verifying ("Number of Iteration must be greater than 0", x => (x > 0)))
      ))

      simEvalForm.bindFromRequest.fold(
        e => BadRequest(Json.obj("message" -> e.toString)),
        f => {
          val (params, algoids, splitTrain, splitTest, evalIteration) = f

          val metricList = params.filter(p => (p("infotype") == "offlineevalmetric")).map(p =>
            OfflineEvalMetric(
              id = 0,
              infoid = p("infoid").asInstanceOf[String],
              evalid = 0, // will be assigned later
              params = p - "infoid" - "infotype" // remove these keys from params
            )).toList

          // percentage param is standard for all splitter
          val percentageParam = Map(
            "trainingPercent" -> (splitTrain.toDouble / 100),
            "validationPercent" -> 0.0, // no validatoin set for sim eval
            "testPercent" -> (splitTest.toDouble / 100)
          )
          val splitterList = params.filter(p => (p("infotype") == "offlineevalsplitter")).map(p =>
            OfflineEvalSplitter(
              id = 0,
              evalid = 0, // will be assigned later
              name = "", // will be assigned later
              infoid = p("infoid").asInstanceOf[String],
              settings = p ++ percentageParam - "infoid" - "infotype" // remove these keys from params
            )).toList

          // get list of algo obj
          val optAlgos: List[Option[Algo]] = algoids.map { algos.get(_) }

          if (metricList.length == 0)
            BadRequest(Json.obj("message" -> "At least one metric is required."))
          else if (splitterList.length == 0)
            BadRequest(Json.obj("message" -> "One Splitter is required."))
          else if (splitterList.length > 1)
            BadRequest(Json.obj("message" -> "Multiple Splitters are not supported now."))
          else if (optAlgos.contains(None))
            BadRequest(Json.obj("message" -> "Invalid algo ids."))
          else {
            val algoList: List[Algo] = optAlgos.map(_.get) // NOTE: already check optAlgos does not contain None

            val evalid = createOfflineEval(eng, algoList, metricList, splitterList(0), evalIteration)

            WS.url(settingsSchedulerUrl + "/users/" + user.id + "/sync").get()

            Ok
          }
        }
      )
  }

  /**
   * Requests to stop and delete simulated evalution (including running/pending job)
   *
   * {{{
   * DELETE
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If not found:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If error:
   *   InternalServerError
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If deleted:
   *   Ok
   *   {
   *      "message" : "Offline evaluation ID $id has been deleted"
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param id the offline evaluation ID
   *
   */
  def removeSimEval(appid: Int, engineid: Int, id: Int) = WithOfflineEval.async(appid, engineid, id) { (user, app, eng, oe) =>
    implicit request =>
      // remove algo, remove metric, remove offline eval
      /** Make sure to unset offline eval's creation time to prevent scheduler from picking up */
      offlineEvals.update(oe.copy(createtime = None))

      /** Deletion of app data and model data could take a while */
      val timeout = play.api.libs.concurrent.Promise.timeout("Scheduler is unreachable. Giving up.", concurrent.duration.Duration(10, concurrent.duration.MINUTES))

      val complete = Helper.stopAndDeleteSimEvalScheduler(appid, engineid, oe.id)

      /** Detect timeout (10 minutes by default) */
      concurrent.Future.firstCompletedOf(Seq(complete, timeout)).map {
        case r: SimpleResult => {
          if (r.header.status == http.Status.OK) {
            Helper.deleteOfflineEval(oe.id, keepSettings = false)
          }
          r
        }
        case t: String => InternalServerError(Json.obj("message" -> t))
      }
  }

  /**
   * Returns the simulated evaluation report
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If not found:
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If found:
   *   Ok
   *   {
   *     "id" : <sim eval id>,
   *     "appid" : <app id>,
   *     "engineid" : <engine id>,
   *     "algolist" : [
   *                    {
   *                      "id" : <algo id>,
   *                      "algoname" : <algo name>,
   *                      "appid" : <app id>,
   *                      "engineid" : <engine id>,
   *                      "algoinfoid" : <algo info id>,
   *                      "algoinfoname" : <algo info name>,
   *                      "settingsstring" : <algo setting string>
   *                    }, ...
   *                  ],
   *     "metricslist" : [
   *                       {
   *                         "id" : <metric id>,
   *                         "metricsinfoid" : <metric info id>,
   *                         "metricsname" : <metric info name>,
   *                         "settingsstring" : <metric setting string>
   *                       }, ...
   *                     ],
   *     "metricscorelist" : [
   *                           {
   *                             "algoid" : <algo id>,
   *                             "metricsid" : <metric id>,
   *                             "score" : <average score>
   *                           }, ...
   *                         ],
   *     "metricscoreiterationlist" : [
   *                                    [{
   *                                      "algoid" : <algo id>,
   *                                      "metricsid" : <metric id>,
   *                                      "score" : <score of 1st iteration>
   *                                     }, ...
   *                                    ],
   *                                    [{
   *                                      "algoid" : <algo id>,
   *                                      "metricsid" : <metric id>,
   *                                      "score" : <score of 2nd iteration>
   *                                     }, ...
   *                                    ],
   *                                  ],
   *     "splittrain" : <training set split percentage 1 to 100>,
   *     "splittest" : <test set split percentage 1 to 100>,
   *     "splittersettingsstring" : <splitter setting string>,
   *     "evaliteration" : <number of iterations>,
   *     "status" : <eval status>,
   *     "starttime" : <start time>,
   *     "endtime" : <end time>
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param id the offline evaluation ID
   */
  def getSimEvalReport(appid: Int, engineid: Int, id: Int) = WithOfflineEval(appid, engineid, id) { (user, app, eng, eval) =>
    implicit request =>

      val status = getSimEvalStatus(eval)

      val evalAlgos = algos.getByOfflineEvalid(eval.id).toArray

      val algolist = Json.toJson(
        evalAlgos.map { algo =>
          val algoInfo = algoInfos.get(algo.infoid)
          algoToJson(algo, appid, algoInfo, withParam = true)
        }.toSeq
      )

      val evalMetrics = offlineEvalMetrics.getByEvalid(eval.id).toArray

      val metricslist = Json.toJson(
        evalMetrics.map { metric =>
          val metricInfo = offlineEvalMetricInfos.get(metric.infoid)
          offlineEvalMetricToJson(metric, metricInfo, withParam = true)
        }.toSeq
      )

      val evalResults = offlineEvalResults.getByEvalid(eval.id).toArray

      val metricscorelist = Json.toJson(
        (for (algo <- evalAlgos; metric <- evalMetrics) yield {

          val results = evalResults
            .filter(x => ((x.metricid == metric.id) && (x.algoid == algo.id)))
            .map(x => x.score)

          val num = results.length
          val avg = if ((results.isEmpty) || (num != eval.iterations)) "N/A" else ((results.reduceLeft(_ + _) / num).toString)

          Json.obj(
            "algoid" -> algo.id,
            "metricsid" -> metric.id,
            "score" -> avg
          )
        }).toSeq
      )

      val metricscoreiterationlist = Json.toJson((for (i <- 1 to eval.iterations) yield {
        val defaultScore = (for (algo <- evalAlgos; metric <- evalMetrics) yield {
          ((algo.id, metric.id) -> "N/A") // default score
        }).toMap

        val evalScore = evalResults.filter(x => (x.iteration == i)).map(r =>
          ((r.algoid, r.metricid) -> r.score.toString)).toMap

        // overwrite defaultScore with evalScore
        (defaultScore ++ evalScore).map {
          case ((algoid, metricid), score) =>
            Json.obj("algoid" -> algoid, "metricsid" -> metricid, "score" -> score)
        }
      }).toSeq)

      val starttime = eval.starttime map (dateTimeToString(_)) getOrElse ("-")
      val endtime = eval.endtime map (dateTimeToString(_)) getOrElse ("-")

      // get splitter data
      val splitters = offlineEvalSplitters.getByEvalid(eval.id)

      if (splitters.hasNext) {
        val splitter = splitters.next

        val splitTrain = ((splitter.settings("trainingPercent").asInstanceOf[Double]) * 100).toInt
        val splitTest = ((splitter.settings("testPercent").asInstanceOf[Double]) * 100).toInt

        if (splitters.hasNext) {
          InternalServerError(Json.obj("message" -> s"More than one splitter found for this Offline Eval ID: ${eval.id}"))
        } else {
          Ok(Json.obj(
            "id" -> eval.id,
            "appid" -> appid,
            "engineid" -> eval.engineid,
            "algolist" -> algolist,
            "metricslist" -> metricslist,
            "metricscorelist" -> metricscorelist,
            "metricscoreiterationlist" -> metricscoreiterationlist,
            "splittrain" -> splitTrain,
            "splittest" -> splitTest,
            "splittersettingsstring" -> offlineEvalSplitterParamToString(splitter, offlineEvalSplitterInfos.get(splitter.infoid)),
            "evaliteration" -> eval.iterations,
            "status" -> status,
            "starttime" -> starttime,
            "endtime" -> endtime
          ))
        }
      } else {
        InternalServerError(Json.obj("message" -> s"No splitter found fo this Offline Eval ID ${eval.id}."))
      }

  }

  /**
   * Returns the algorithm auto tune report
   *
   * {{{
   * GET
   * JSON parameters:
   *   None
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If not found:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If found:
   *   Ok
   *   {
   *     "id" : <original algo id>,
   *     "appid" : <app id>,
   *     "engineid" : <engine id>,
   *     "algo" : {
   *                "id" : <original algo id>,
   *                "algoname" : <algo name>,
   *                "appid" : <app id>,
   *                "engineid" : <engine id>,
   *                "algoinfoid" : <algo info id>,
   *                "algoinfoname" : <algo info name>,
   *                "settingsstring" : <algo setting string>
   *              },
   *     "metric" : {
   *                  "id" : <metric id>,
   *                  "metricsinfoid" : <metric info id>,
   *                  "metricsname" : <metric info name>,
   *                  "settingsstring" : <metric setting string>
   *                },
   *     "metricscorelist" : [
   *                           {
   *                             "algoautotuneid" : <tuned algo id>,
   *                             "algoinfoname" : <algo info name>,
   *                             "settingsstring" : <algo setting string>,
   *                             "score" : <average score>
   *                           }, ...
   *                         ],
   *     "metricscoreiterationlist" : [
   *                                    [ {
   *                                        "algoautotuneid" : <tuned algo id 1>,
   *                                        "algoinfoname" : <algo info name>,
   *                                        "settingsstring" : <algo setting string>,
   *                                        "score" : <score of 1st iteration for this tuned algo id>
   *                                      },
   *                                      {
   *                                        "algoautotuneid" : <tuned algo id 2>,
   *                                        "algoinfoname" : <algo info name>,
   *                                        "settingsstring" : <algo setting string>,
   *                                        "score" : <score of 1st iteration for this tuned algo id>
   *                                      }, ...
   *                                    ],
   *                                    [ {
   *                                        "algoautotuneid" : <tuned algo id 1>,
   *                                        "algoinfoname" : <algo info name>,
   *                                        "settingsstring" : <algo setting string>,
   *                                        "score" : <score of 2nd iteration for this tuned algo id>
   *                                      },
   *                                      {
   *                                        "algoautotuneid" : <tuned algo id 2>,
   *                                        "algoinfoname" : <algo info name>,
   *                                        "settingsstring" : <algo setting string>,
   *                                        "score" : <score of 2nd iteration for this tuned algo id>
   *                                      }, ...
   *                                    ], ...
   *                                  ],
   *     "splittrain" : <training set split percentage 1 to 100>,
   *     "splitvalidation" : <validation set split percentage 1 to 100>,
   *     "splittest" : <test set split percentage 1 to 100>,
   *     "splitmethod" : <split method string: randome, time>
   *     "splittersettingsstring" : <splitter setting string>,
   *     "evaliteration" : <number of iterations>,
   *     "status" : <auto tune status>,
   *     "starttime" : <start time>,
   *     "endtime" : <end time>
   *   }
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param algoid the algo ID
   */
  def getAlgoAutotuningReport(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, eng, algo) =>
    implicit request =>

      algo.offlinetuneid map { tuneid =>
        offlineTunes.get(tuneid) map { tune =>

          val algoInfo = algoInfos.get(algo.infoid)

          // get all offlineeval of this offlinetuneid
          val tuneOfflineEvals: Array[OfflineEval] = offlineEvals.getByTuneid(tuneid).toArray.sortBy(_.id)

          val tuneMetrics: Array[OfflineEvalMetric] = tuneOfflineEvals.flatMap { e => offlineEvalMetrics.getByEvalid(e.id) }

          val tuneSplitters: Array[OfflineEvalSplitter] = tuneOfflineEvals.flatMap { e => offlineEvalSplitters.getByEvalid(e.id) }

          // get all offlineeavlresults of each offlineevalid
          val tuneOfflineEvalResults: Array[OfflineEvalResult] = tuneOfflineEvals.flatMap { e => offlineEvalResults.getByEvalid(e.id) }

          // test set score
          val tuneOfflineEvalResultsTestSet: Array[OfflineEvalResult] = tuneOfflineEvalResults.filter(x => (x.splitset == "test"))

          val tuneOfflineEvalResultsTestSetAlgoidMap: Map[Int, Double] = tuneOfflineEvalResultsTestSet.map(x => (x.algoid -> x.score)).toMap

          // get all algos of each offlineevalid
          // note: this happen after getting all available offlineEvalResults,
          // so these retrieved algos may have more algo than those used in offlineEvalResults.
          val tuneAlgos: Array[Algo] = tuneOfflineEvals flatMap { e => algos.getByOfflineEvalid(e.id) }

          val tuneAlgosMap: Map[Int, Algo] = tuneAlgos.map { a => (a.id -> a) }.toMap

          // group by (loop, paramset)
          type AlgoGroupIndex = (Option[Int], Option[Int])

          val tuneAlgosGroup: Map[AlgoGroupIndex, Array[Algo]] = tuneAlgos.groupBy(a => (a.loop, a.paramset))

          // get param of each group
          val tuneAlgosGroupParams: Map[AlgoGroupIndex, (Int, String, String)] = tuneAlgosGroup.map {
            case (index, arrayOfAlgos) =>
              val tAlgo = arrayOfAlgos(0) // just take 1, all algos of this group will have same params
              val tAlgoInfo: Option[AlgoInfo] = algoInfos.get(tAlgo.infoid)
              val infoName = tAlgoInfo.map(_.name).getOrElse("Algo info ${tAlgo.infoid} not found")
              val settings = algoParamToString(tAlgo, tAlgoInfo)

              (index -> (tAlgo.id, settings, infoName))
          }

          // calculate avg
          val avgScores: Map[AlgoGroupIndex, String] = tuneAlgosGroup.mapValues { arrayOfAlgos =>
            // check if all scores available
            val allAvailable = arrayOfAlgos.map(algo => tuneOfflineEvalResultsTestSetAlgoidMap.contains(algo.id)).reduceLeft(_ && _)

            if (allAvailable) {
              val scores: Array[Double] = arrayOfAlgos.map(algo => tuneOfflineEvalResultsTestSetAlgoidMap(algo.id))

              (scores.sum / scores.size).toString
            } else {
              "N/A"
            }
          }

          val metricscorelist = avgScores.toSeq.sortBy(_._1).map {
            case (k, v) =>
              Json.obj(
                "algoautotuneid" -> tuneAlgosGroupParams(k)._1,
                "algoinfoname" -> tuneAlgosGroupParams(k)._3,
                "settingsstring" -> tuneAlgosGroupParams(k)._2,
                "score" -> v)
          }

          val metricscoreiterationlist = tuneOfflineEvals.map { e =>
            tuneOfflineEvalResultsTestSet.filter(x => (x.evalid == e.id)).sortBy(_.algoid).map { r =>

              val tAlgo = tuneAlgosMap(r.algoid)
              val tAlgoInfo: Option[AlgoInfo] = algoInfos.get(tAlgo.infoid)
              val infoName = tAlgoInfo.map(_.name).getOrElse("Algo info ${tAlgo.infoid} not found")

              Json.obj(
                "algoautotuneid" -> r.algoid,
                "algoinfoname" -> infoName,
                "settingsstring" -> algoParamToString(tAlgo, tAlgoInfo),
                "score" -> r.score)
            }.toSeq
          }.toSeq

          val metric = tuneMetrics(0)
          val metricInfo = offlineEvalMetricInfos.get(metric.infoid)
          val splitter = tuneSplitters(0)
          val splitTrain = ((splitter.settings("trainingPercent").asInstanceOf[Double]) * 100).toInt
          val splitValidation = ((splitter.settings("validationPercent").asInstanceOf[Double]) * 100).toInt
          val splitTest = ((splitter.settings("testPercent").asInstanceOf[Double]) * 100).toInt
          val evalIteration = tuneOfflineEvals.size // NOTE: for autotune, number of offline eval is the iteration
          val engineinfoid = engines.get(engineid) map { _.infoid } getOrElse { "unkown-engine" }

          val starttime = tune.starttime map (dateTimeToString(_)) getOrElse ("-")
          val endtime = tune.endtime map (dateTimeToString(_)) getOrElse ("-")

          Ok(Json.obj(
            "id" -> algoid,
            "appid" -> appid,
            "engineid" -> engineid,
            "algo" -> algoToJson(algo, appid, algoInfo, withParam = true),
            "metric" -> offlineEvalMetricToJson(metric, metricInfo, withParam = true),
            "metricscorelist" -> Json.toJson(metricscorelist),
            "metricscoreiterationlist" -> Json.toJson(metricscoreiterationlist),
            "splittrain" -> splitTrain,
            "splitvalidation" -> splitValidation,
            "splittest" -> splitTest,
            "splittersettingsstring" -> offlineEvalSplitterParamToString(splitter, offlineEvalSplitterInfos.get(splitter.infoid)),
            "evaliteration" -> evalIteration,
            "status" -> getOfflineTuneStatus(tune),
            "starttime" -> starttime,
            "endtime" -> endtime
          ))
        } getOrElse {
          InternalServerError(Json.obj("message" -> s"The offline tune id ${tuneid} does not exist."))
        }
      } getOrElse {
        InternalServerError(Json.obj("message" -> "This algo does not have offline tune."))
      }
  }

  /**
   * Applies the selected tuned algo's params to this algo
   *
   * {{{
   * POST
   * JSON parameters:
   *   {
   *     "tunedalgoid" : <the tuned algo id. This algo's parameters will be used>
   *   }
   * JSON response:
   *   If not authenticated:
   *   Forbidden
   *   {
   *     "message" : "Haven't signed in yet."
   *   }
   *
   *   If error:
   *   BadRequest
   *   {
   *     "message" : <error message>
   *   }
   *
   *   If algo not found:
   *   NotFound
   *   {
   *     "message" : <error message>
   *   }
   *   If applied:
   *   Ok
   *
   * }}}
   *
   * @param appid the App ID
   * @param engineid the engine ID
   * @param algoid the algo ID to which the tuned parameters are applied
   */
  def algoAutotuningSelect(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, eng, algo) =>
    implicit request =>

      // Apply POST request params of tunedalgoid to algoid
      // update the status of algoid from 'tuning' or 'tuned' to 'ready'

      val form = Form("tunedalgoid" -> number)

      form.bindFromRequest.fold(
        formWithError => {
          val msg = formWithError.errors(0).message // extract 1st error message only
          BadRequest(toJson(Map("message" -> toJson(msg))))
        },
        formData => {
          val tunedAlgoid = formData

          val orgAlgo = algos.get(algoid)
          val tunedAlgo = algos.get(tunedAlgoid)

          if ((orgAlgo == None) || (tunedAlgo == None)) {
            NotFound(toJson(Map("message" -> toJson("Invalid app id, engine id or algo id."))))
          } else {
            val tunedAlgoParams = tunedAlgo.get.params ++ Map("tune" -> "manual")
            algos.update(orgAlgo.get.copy(
              params = tunedAlgoParams,
              status = "ready"
            ))

            Ok
          }
        }
      )
  }

  def getEngineSettings(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, engine) =>
    implicit request =>
      engineInfos.get(engine.infoid) map { engineInfo =>
        val params = engineInfo.params.mapValues(_.defaultvalue) ++ engine.params

        Ok(toJson(Map(
          "id" -> toJson(engine.id), // engine id
          "appid" -> toJson(engine.appid),
          "allitemtypes" -> toJson(engine.itypes == None),
          "itemtypelist" -> engine.itypes.map(x => toJson(x.toIterator.toSeq)).getOrElse(JsNull)) ++
          (params map { case (k, v) => (k, toJson(v.toString)) })))
      } getOrElse {
        NotFound(toJson(Map("message" -> toJson(s"Invalid EngineInfo ID: ${engine.infoid}"))))
      }
  }

  def updateEngineSettings(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, engine) =>
    implicit request =>
      val f = Form(tuple(
        "infoid" -> mapOfStringToAny,
        "allitemtypes" -> boolean,
        "itemtypelist" -> list(text)))
      f.bindFromRequest.fold(
        e => BadRequest(toJson(Map("message" -> toJson(e.toString)))),
        f => {
          val (params, allitemtypes, itemtypelist) = f
          // NOTE: read-modify-write the original param
          val itypes = if (itemtypelist.isEmpty) None else Option(itemtypelist)
          val updatedParams = engine.params ++ params - "infoid"
          val updatedEngine = engine.copy(itypes = itypes, params = updatedParams)
          engines.update(updatedEngine)
          Ok
        })
  }

  def getEngineTemplateHtml(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, engine) =>
    implicit request =>
      //Ok(views.html.engines.template(engine.infoid))
      engineInfos.get(engine.infoid) map { engineInfo =>
        if (engineInfo.paramsections.isEmpty)
          Ok(views.html.engines.template(handleParamSections[EngineInfo](Seq(ParamSection(
            name = "Parameter Settings",
            description = Some("No extra setting is required for this engine."))), engineInfo, 1), true))
        else
          Ok(views.html.engines.template(handleParamSections[EngineInfo](engineInfo.paramsections, engineInfo, 1), false))
      } getOrElse {
        NotFound(s"EngineInfo ID ${engine.infoid} not found")
      }
  }

  def getEngineTemplateJs(appid: Int, engineid: Int) = WithEngine(appid, engineid) { (user, app, engine) =>
    implicit request =>
      Ok(views.js.engines.template(engine.infoid, Seq()))
      engineInfos.get(engine.infoid) map { engineInfo =>
        Ok(views.js.engines.template(
          engineInfo.id,
          engineInfo.paramsections.map(collectParams(engineInfo, _)).foldLeft(Set[Param]())(_ ++ _).toSeq))
      } getOrElse {
        NotFound(s"EngineInfo ID ${engine.infoid} not found")
      }
  }

  def getAlgoSettings(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, engine, algo) =>
    implicit request =>
      algoInfos.get(algo.infoid) map { algoInfo =>
        // get default params from algoinfo and combined with existing params
        val params = algoInfo.params.mapValues(_.defaultvalue) ++ algo.params

        Ok(toJson(Map(
          "id" -> toJson(algo.id),
          "appid" -> toJson(appid),
          "engineid" -> toJson(engineid)) ++
          (params map { case (k, v) => (k, toJson(v.toString)) })))
      } getOrElse {
        NotFound(toJson(Map("message" -> toJson(s"Invalid AlgoInfo ID: ${algo.infoid}"))))
      }
  }

  def updateAlgoSettings(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, engine, algo) =>
    implicit request =>
      val f = Form(tuple("infoid" -> mapOfStringToAny, "tune" -> text, "tuneMethod" -> text))
      f.bindFromRequest.fold(
        e => BadRequest(toJson(Map("message" -> toJson(e.toString)))),
        bound => {
          val (params, tune, tuneMethod) = bound
          // NOTE: read-modify-write the original param
          val updatedParams = algo.params ++ params ++ Map("tune" -> tune, "tuneMethod" -> tuneMethod) - "infoid"
          val updatedAlgo = algo.copy(params = updatedParams)

          if (updatedParams("tune") != "auto") {
            algos.update(updatedAlgo)
            Ok
          } else {
            // create offline eval with baseline algo
            // TODO: get from UI
            val defaultBaseLineAlgoType = engine.infoid match {
              case "itemrec" => "pdio-randomrank"
              case "itemsim" => "pdio-itemsimrandomrank"
            }

            engineInfos.get(engine.infoid).map { engineInfo =>
              val metricinfoid = engineInfo.defaultofflineevalmetricinfoid // TODO: from UI
              val splitterinfoid = engineInfo.defaultofflineevalsplitterinfoid // TODO: from UI
              algoInfos.get(defaultBaseLineAlgoType).map { baseLineAlgoInfo =>
                offlineEvalMetricInfos.get(metricinfoid).map { metricInfo =>
                  offlineEvalSplitterInfos.get(splitterinfoid).map { splitterInfo =>

                    // delete previous offlinetune stuff if the algo's offlinetuneid != None
                    if (updatedAlgo.offlinetuneid != None) {
                      val tuneid = updatedAlgo.offlinetuneid.get

                      offlineTunes.get(tuneid) map { tune =>
                        /** Make sure to unset offline tune's creation time to prevent scheduler from picking up */
                        offlineTunes.update(tune.copy(createtime = None))

                        // TODO: check scheduler err
                        Helper.stopAndDeleteOfflineTuneScheduler(appid.toInt, engineid.toInt, tuneid)
                        Future {
                          Helper.deleteOfflineTune(tuneid, keepSettings = false)
                        }
                      }
                    }

                    // auto tune
                    algos.update(updatedAlgo)

                    // create an OfflineTune and paramGen
                    val offlineTune = OfflineTune(
                      id = -1,
                      engineid = updatedAlgo.engineid,
                      loops = 5, // TODO: default 5 now
                      createtime = None, // NOTE: no createtime yet
                      starttime = None,
                      endtime = None
                    )

                    val tuneid = offlineTunes.insert(offlineTune)
                    Logger.info("Create offline tune ID " + tuneid)

                    paramGens.insert(ParamGen(
                      id = -1,
                      infoid = "random", // TODO: default random scan param gen now
                      tuneid = tuneid,
                      params = Map() // TODO: param for param gen
                    ))

                    // update original algo status to tuning
                    algos.update(updatedAlgo.copy(
                      offlinetuneid = Some(tuneid),
                      status = "tuning"
                    ))

                    val baseLineAlgo = Algo(
                      id = -1,
                      engineid = updatedAlgo.engineid,
                      name = "Default-BasedLine-Algo-for-OfflineTune-" + tuneid,
                      infoid = baseLineAlgoInfo.id,
                      command = "",
                      params = baseLineAlgoInfo.params.mapValues(_.defaultvalue),
                      settings = Map(), // no use for now
                      modelset = false, // init value
                      createtime = DateTime.now,
                      updatetime = DateTime.now,
                      status = "simeval",
                      offlineevalid = None,
                      offlinetuneid = Some(tuneid),
                      loop = Some(0), // loop=0 reserved for autotune baseline
                      paramset = None
                    )

                    val metric = OfflineEvalMetric(
                      id = 0,
                      infoid = metricInfo.id,
                      evalid = 0, // will be assigned later
                      params = metricInfo.params.mapValues(_.defaultvalue)
                    )

                    // percentage param is standard for all splitter
                    // TODO: hardcode percentage for auto tune for now. get from UI
                    val percentageParam = Map(
                      "trainingPercent" -> 0.55,
                      "validationPercent" -> 0.2,
                      "testPercent" -> 0.2
                    )

                    val splitter = OfflineEvalSplitter(
                      id = 0,
                      evalid = 0, // will be assigned later
                      name = "", // will be assigned later
                      infoid = splitterInfo.id,
                      settings = splitterInfo.params.mapValues(_.defaultvalue) ++ percentageParam
                    )

                    // TODO: get iterations, metric info, etc from UI, now hardcode to 3.
                    for (i <- 1 to 3) {
                      createOfflineEval(engine, List(baseLineAlgo), List(metric), splitter, 1, Some(tuneid))
                    }

                    // after everything has setup,
                    // update with createtime, so scheduler can know it's ready to be picked up
                    offlineTunes.update(offlineTune.copy(
                      id = tuneid,
                      createtime = Some(DateTime.now)
                    ))

                    // call sync to scheduler here
                    WS.url(settingsSchedulerUrl + "/users/" + user.id + "/sync").get()

                    Ok

                  }.getOrElse(InternalServerError(Json.obj("message" -> s"OfflineEvalSplitterInfo ID ${splitterinfoid} not found.")))
                }.getOrElse(InternalServerError(Json.obj("message" -> s"OfflineEvalMetricInfo ID ${metricinfoid} not found.")))
              }.getOrElse(InternalServerError(Json.obj("message" -> s"AlgoInfo ID ${defaultBaseLineAlgoType} not found.")))
            }.getOrElse(InternalServerError(Json.obj("message" -> s"EngineInfo ID ${engine.infoid} not found.")))
          }
        })
  }

  def getAlgoTemplateHtml(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, engine, algo) =>
    implicit request =>
      algoInfos.get(algo.infoid) map { algoInfo =>
        if (algoInfo.paramsections.isEmpty)
          Ok(views.html.algos.template(handleParamSections[AlgoInfo](Seq(ParamSection(
            name = "Parameter Settings",
            description = Some("No extra setting is required for this algorithm."))), algoInfo, 1), true))
        else
          Ok(views.html.algos.template(handleParamSections[AlgoInfo](algoInfo.paramsections, algoInfo, 1), false))
      } getOrElse {
        NotFound(s"AlgoInfo ID ${algo.infoid} not found")
      }
  }

  def getAlgoTemplateJs(appid: Int, engineid: Int, algoid: Int) = WithAlgo(appid, engineid, algoid) { (user, app, engine, algo) =>
    implicit request =>
      algoInfos.get(algo.infoid) map { algoInfo =>
        Ok(views.js.algos.template(
          algoInfo.id,
          algoInfo.paramsections.map(collectParams(algoInfo, _)).foldLeft(Set[Param]())(_ ++ _).toSeq,
          algoInfo.paramsections.map(collectParams(algoInfo, _, true)).foldLeft(Set[Param]())(_ ++ _).toSeq))
      } getOrElse {
        NotFound(s"AlgoInfo ID ${algo.infoid} not found")
      }
  }

  def getMetricInfoTemplateHtml(engineinfoid: String, metricinfoid: String) = WithUser { user =>
    implicit request =>
      offlineEvalMetricInfos.get(metricinfoid) map { metricInfo =>
        if (metricInfo.paramsections.isEmpty)
          Ok(views.html.metrics.template(handleParamSections[OfflineEvalMetricInfo](Seq(ParamSection(
            name = "Parameter Settings",
            description = Some("No extra setting is required for this metric."))), metricInfo, 1), true))
        else
          Ok(views.html.metrics.template(handleParamSections[OfflineEvalMetricInfo](metricInfo.paramsections, metricInfo, 1), false))
      } getOrElse {
        NotFound(s"OfflineEvalMetricInfo ID ${metricinfoid} not found")
      }
  }

  def getSplitterInfoTemplateHtml(engineinfoid: String, splitterinfoid: String) = WithUser { user =>
    implicit request =>
      offlineEvalSplitterInfos.get(splitterinfoid) map { splitterInfo =>
        if (splitterInfo.paramsections.isEmpty)
          Ok(views.html.splitters.template(handleParamSections[OfflineEvalSplitterInfo](Seq(ParamSection(
            name = "Parameter Settings",
            description = Some("No extra setting is required for this splitter."))), splitterInfo, 1), true))
        else
          Ok(views.html.splitters.template(handleParamSections[OfflineEvalSplitterInfo](splitterInfo.paramsections, splitterInfo, 1), false))
      } getOrElse {
        NotFound(s"OfflineEvalSplitterInfo ID ${splitterinfoid} not found")
      }
  }

  def collectParams[T <: Info](info: T, paramsection: ParamSection, tuning: Boolean = false): Set[Param] = {
    if (tuning)
      if (paramsection.sectiontype == "tuning")
        paramsection.params.map(_.map(info.params(_)).toSet).getOrElse(Set()) ++
          paramsection.subsections.map(_.map(collectParams(info, _, false)).reduce(_ ++ _)).getOrElse(Set())
      else
        paramsection.subsections.map(_.map(collectParams(info, _, tuning)).reduce(_ ++ _)).getOrElse(Set())
    else
      paramsection.params.map(_.map(info.params(_)).toSet).getOrElse(Set()) ++
        paramsection.subsections.map(_.map(collectParams(info, _, tuning)).reduce(_ ++ _)).getOrElse(Set())
  }

  def handleParam[T <: Info](param: Param, info: T, tuning: Boolean = false): String = {
    val content = param.ui.uitype match {
      case "selection" =>
        uiSelection[T](info, param.id, param.name, param.description, param.ui.selections.map(_.map(s => (s.name, s.value))).get, Some(param.defaultvalue.toString))
      case "slider" =>
        uiSlider[T](info, param.id, param.name, param.description)
      case _ =>
        if (tuning)
          uiTextPair[T](info, param.id + "Min", param.id + "Max", param.name, param.description)
        else
          uiText[T](info, param.id, param.name, param.description, Some(param.defaultvalue.toString))
    }
    content.toString
  }

  def handleParamSections[T <: Info](paramsections: Seq[ParamSection], info: T, level: Int, tuning: Boolean = false): String = {
    paramsections map { paramsection =>
      if (paramsection.sectiontype == "tuning")
        views.html.algos.sectionmanualauto(
          paramsection.name,
          handleParamSectionContent[T](paramsection, info, level),
          handleParamSectionContent[T](paramsection, info, level, true))
      else if (level > 1)
        uiSection2[T](info, paramsection.name, paramsection.description, handleParamSectionContent[T](paramsection, info, level, tuning))
      else
        uiSection1[T](info, paramsection.name, paramsection.description, handleParamSectionContent[T](paramsection, info, level, tuning))
    } mkString ""
  }

  def handleParamSectionContent[T <: Info](paramsection: ParamSection, info: T, level: Int, tuning: Boolean = false) = {
    paramsection.params.map(_.map(p => handleParam[T](info.params(p), info, tuning)).mkString).getOrElse("") +
      paramsection.subsections.map(handleParamSections[T](_, info, level + 1, tuning)).getOrElse("")
  }

  def uiText[T <: Info](info: T, id: String, name: String, description: Option[String], defaultValue: Option[String] = None) = {
    info match {
      case _: AlgoInfo =>
        views.html.algos.text(id, name, description)
      case _: EngineInfo =>
        views.html.engines.text(id, name, description)
      case _: OfflineEvalMetricInfo =>
        views.html.metrics.text(id, name, description, defaultValue)
      case _: OfflineEvalSplitterInfo =>
        views.html.splitters.text(id, name, description, defaultValue)
    }
  }

  def uiTextPair[T <: Info](info: T, id1: String, id2: String, name: String, description: Option[String]) = {
    views.html.algos.textpair(id1, id2, name, description)
  }

  def uiSlider[T <: Info](info: T, id: String, name: String, description: Option[String]) = {
    views.html.engines.slider(id, name, description)
  }

  def uiSelection[T <: Info](info: T, id: String, name: String, description: Option[String], selections: Seq[(String, String)], defaultValue: Option[String] = None) = {
    info match {
      case _: AlgoInfo =>
        views.html.algos.selection(id, name, description, selections)
      case _: EngineInfo =>
        views.html.engines.selection(id, name, description, selections)
      case _: OfflineEvalMetricInfo =>
        views.html.metrics.selection(id, name, description, selections, defaultValue)
      case _: OfflineEvalSplitterInfo =>
        views.html.splitters.selection(id, name, description, selections, defaultValue)
    }
  }

  def uiSection1[T <: Info](info: T, name: String, description: Option[String], content: String) = {
    info match {
      case _: AlgoInfo =>
        views.html.algos.section1(name, description, content)
      case _: EngineInfo =>
        views.html.engines.section1(name, description, content)
      case _: OfflineEvalMetricInfo =>
        views.html.metrics.section1(name, description, content)
      case _: OfflineEvalSplitterInfo =>
        views.html.splitters.section1(name, description, content)
    }
  }

  def uiSection2[T <: Info](info: T, name: String, description: Option[String], content: String) = {
    info match {
      case _: AlgoInfo =>
        views.html.algos.section2(name, description, content)
      case _: EngineInfo =>
        views.html.engines.section2(name, description, content)
      // OfflineEvalMetricInfo doesn't support section2
      // OfflineEvalSplitterInfo doesn't support section2
    }
  }
}
