<commit_before>package de.frosner.broccoli.controllers

import java.io.FileNotFoundException
import javax.inject.Inject

import de.frosner.broccoli.models.InstanceStatusJson._
import de.frosner.broccoli.models.InstanceStatus.InstanceStatus
import de.frosner.broccoli.models.{Instance, InstanceCreation, InstanceStatus, InstanceWithStatus}
import de.frosner.broccoli.conf
import Instance.instanceApiWrites
import InstanceCreation.{instanceCreationReads, instanceCreationWrites}
import de.frosner.broccoli.services.{InstanceService, PermissionsService, TemplateNotFoundException}
import de.frosner.broccoli.services.InstanceService._
import de.frosner.broccoli.util.Logging
import play.api.libs.json.{JsObject, JsString, Json}
import play.api.mvc.{Action, Controller}

import scala.util.{Failure, Success}

class InstanceController @Inject() (instanceService: InstanceService,
                                    permissionsService: PermissionsService) extends Controller with Logging {

  def list(maybeTemplateId: Option[String]) = Action {
    val maybeInstances = instanceService.getInstances
    val maybeFilteredInstances = maybeTemplateId.map(
      id => maybeInstances.map(_.filter(_.instance.template.id == id))
    ).getOrElse(maybeInstances)
    val maybeAnonymizedInstances = if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
      maybeFilteredInstances
    } else {
      maybeFilteredInstances.map(_.map(InstanceController.removeSecretVariables))
    }
    maybeAnonymizedInstances match {
      case Success(filteredInstances) => Ok(Json.toJson(filteredInstances))
      case Failure(throwable) => NotFound(throwable.toString)
    }
  }

  def show(id: String) = Action {
    val maybeInstance = instanceService.getInstance(id)
    maybeInstance.map {
      instance => Ok(Json.toJson{
        if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
          instance
        } else {
          InstanceController.removeSecretVariables(instance)
        }
      })
    }.recover {
      case throwable => NotFound(throwable.toString)
    }.get
  }

  def create = Action { request =>
    if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
      val maybeValidatedInstanceCreation = request.body.asJson.map(_.validate[InstanceCreation])
      maybeValidatedInstanceCreation.map { validatedInstanceCreation =>
        validatedInstanceCreation.map { instanceCreation =>
          val tryNewInstance = instanceService.addInstance(instanceCreation)
          tryNewInstance.map { instanceWithStatus =>
            Status(201)(Json.toJson(instanceWithStatus)).withHeaders(
              LOCATION -> s"/api/v1/instances/${instanceWithStatus.instance.id}" // TODO String constant
            )
          }.recover { case error =>
            Status(400)("Invalid JSON format: " + error.toString)
          }.get
        }.getOrElse(Status(400)("Expected JSON data"))
      }.getOrElse(Status(400)("Expected JSON data"))
    } else {
      Status(403)(s"Broccoli must be running in '${conf.PERMISSIONS_MODE_ADMINISTRATOR}' " +
        s"permissions mode to allow the creation of instances.")
    }
  }


  def update(id: String) = Action { request =>
    if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_USER) {
      Status(403)(s"Updating instances now allowed when running in permissions mode '${conf.PERMISSIONS_MODE_USER}'.")
    } else {
      val maybeJsObject = request.body.asJson.map(_.as[JsObject])
      maybeJsObject.map { jsObject =>
        // extract updates
        val fields = jsObject.value
        val maybeStatusUpdater = fields.get("status").flatMap { value =>
          val maybeValidatedNewStatus = value.validate[InstanceStatus]
          maybeValidatedNewStatus.map(status => Some(StatusUpdater(status))).getOrElse(None)<commit_msg>#144 more generic error message<commit_after>package de.frosner.broccoli.controllers

import java.io.FileNotFoundException
import javax.inject.Inject

import de.frosner.broccoli.models.InstanceStatusJson._
import de.frosner.broccoli.models.InstanceStatus.InstanceStatus
import de.frosner.broccoli.models.{Instance, InstanceCreation, InstanceStatus, InstanceWithStatus}
import de.frosner.broccoli.conf
import Instance.instanceApiWrites
import InstanceCreation.{instanceCreationReads, instanceCreationWrites}
import de.frosner.broccoli.services.{InstanceService, PermissionsService, TemplateNotFoundException}
import de.frosner.broccoli.services.InstanceService._
import de.frosner.broccoli.util.Logging
import play.api.libs.json.{JsObject, JsString, Json}
import play.api.mvc.{Action, Controller}

import scala.util.{Failure, Success}

class InstanceController @Inject() (instanceService: InstanceService,
                                    permissionsService: PermissionsService) extends Controller with Logging {

  def list(maybeTemplateId: Option[String]) = Action {
    val maybeInstances = instanceService.getInstances
    val maybeFilteredInstances = maybeTemplateId.map(
      id => maybeInstances.map(_.filter(_.instance.template.id == id))
    ).getOrElse(maybeInstances)
    val maybeAnonymizedInstances = if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
      maybeFilteredInstances
    } else {
      maybeFilteredInstances.map(_.map(InstanceController.removeSecretVariables))
    }
    maybeAnonymizedInstances match {
      case Success(filteredInstances) => Ok(Json.toJson(filteredInstances))
      case Failure(throwable) => NotFound(throwable.toString)
    }
  }

  def show(id: String) = Action {
    val maybeInstance = instanceService.getInstance(id)
    maybeInstance.map {
      instance => Ok(Json.toJson{
        if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
          instance
        } else {
          InstanceController.removeSecretVariables(instance)
        }
      })
    }.recover {
      case throwable => NotFound(throwable.toString)
    }.get
  }

  def create = Action { request =>
    if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_ADMINISTRATOR) {
      val maybeValidatedInstanceCreation = request.body.asJson.map(_.validate[InstanceCreation])
      maybeValidatedInstanceCreation.map { validatedInstanceCreation =>
        validatedInstanceCreation.map { instanceCreation =>
          val tryNewInstance = instanceService.addInstance(instanceCreation)
          tryNewInstance.map { instanceWithStatus =>
            Status(201)(Json.toJson(instanceWithStatus)).withHeaders(
              LOCATION -> s"/api/v1/instances/${instanceWithStatus.instance.id}" // TODO String constant
            )
          }.recover { case error =>
            Status(400)(error.toString)
          }.get
        }.getOrElse(Status(400)("Expected JSON data"))
      }.getOrElse(Status(400)("Expected JSON data"))
    } else {
      Status(403)(s"Broccoli must be running in '${conf.PERMISSIONS_MODE_ADMINISTRATOR}' " +
        s"permissions mode to allow the creation of instances.")
    }
  }


  def update(id: String) = Action { request =>
    if (permissionsService.getPermissionsMode == conf.PERMISSIONS_MODE_USER) {
      Status(403)(s"Updating instances now allowed when running in permissions mode '${conf.PERMISSIONS_MODE_USER}'.")
    } else {
      val maybeJsObject = request.body.asJson.map(_.as[JsObject])
      maybeJsObject.map { jsObject =>
        // extract updates
        val fields = jsObject.value
        val maybeStatusUpdater = fields.get("status").flatMap { value =>
          val maybeValidatedNewStatus = value.validate[InstanceStatus]
          maybeValidatedNewStatus.map(status => Some(StatusUpdater(status))).getOrElse(None)
{'fraction_non_alphanumeric': 0.09739422084623323, 'fraction_numerical': 0.005288957688338493, 'mean_word_length': 3.8215174129353233, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1085789', 'n_tokens_mistral': 2211, 'n_tokens_neox': 2139, 'n_words': 388}