package com.weEat.controllers import com.weEat.models.{FoodNode => FoodNodeCollection} import com.weEat.services.MongoDBService import com.weEat.shared.models._ import javax.inject.{Inject,Singleton} import play.api.libs.json._ import play.api.mvc._ import org.bson.types.ObjectId import org.mongodb.scala.model.Filters._ import scala.concurrent.Future import scala.util.{Success,Failure} import com.weEat.models.Authorization import scalaoauth2.provider.{AuthInfoRequest,OAuth2ProviderActionBuilders} import com.weEat.services.OAuth2Service @Singleton class FoodController @Inject()( val controllerComponents: ControllerComponents, oauth: OAuth2Service, db: MongoDBService ) extends BaseController with OAuth2ProviderActionBuilders { implicit val ec = scala.concurrent.ExecutionContext.global import db.withCollection def get(id: String) = Action.async { implicit request: Request[AnyContent] => withCollection(FoodNodeCollection) {collection => collection.find(equal("id", id)) .first() .toFuture() .transform({ case Success(x) => Success(Ok(Json.toJson(x))) case Failure(x) => throw x }) }.flatten } def all() = Action.async { implicit request: Request[AnyContent] => withCollection(FoodNodeCollection) {collection => collection.find() .toFuture() .transform({ case Success(x) => Success(Ok(Json.toJson(x))) case Failure(x) => throw x }) }.flatten } def query(q: String) = Action.async { implicit request: Request[AnyContent] => withCollection(FoodNodeCollection) {collection => collection.find(regex("name", q, "i")) .toFuture() .transform({ case Success(x) => Success(Ok(Json.toJson(x))) case Failure(x) => throw x }) }.flatten } // def getImage(foodId: String, idx: Int) = Action.async // { implicit request: Request[AnyContent] => // withCollection(FoodImages) {collection => // collection.find(and(equal("food", foodId), equal("index", idx))) // .first() // .toFuture() // .transform({ // case Success(img) => // Success(Ok.streamed(img.data, img.data.length, img.mime)) // case Failure(x) => throw x // }) // }.flatten // ??? // } // def addImageTo(id: String) = Action.async(parse.byteString) // { implicit request: Request[ByteString] => // withCollection(FoodImages) { images => // images.insertOne(FoodImage(None, id, , request.body, request.contentType.get)) // .head().transformWith({ // case Success(img) => withCollection(FoodNode) { foods => // foods.findOneAndUpdate( // equal("id", id), // push("imageIds", img._id.get) // ).head().transform({ // case Success(x) => Success(Ok(x)) // case Failure(x) => // images.deleteOne(eq("_id", img._id.get)) // throw x // }) // } // case Failure(x) => throw x // }) // }.flatten // ??? // } // def deleteImage(foodId: String, imageId: String) = Action.async // { implicit request: Request[AnyContent] => // withCollection(FoodNode) { foods => // foods.findOneAndUpdate( // equal("id", foodId), // pull("imageIds", imageId) // ).head().transformWith({ // case Success(x) => images.deleteOne(eq("_id", img._id.get)) // .head().transform({ // case Success(x) => Success(Ok(x)) // case Failure(x) => throw x // }) // case Failure(x) => throw x // }) // }.flatten // ??? // } def add(uid: Option[String]) = AuthorizedAction[Authorization](oauth) .async(parse.json) { implicit request: AuthInfoRequest[JsValue, Authorization] => try { val food = request.body.as[FoodNode].withId( new ObjectId, uid.flatMap({ id => if (request.authInfo.user.hasAdminPermissions) Some(new ObjectId(id)) else None }).getOrElse(request.authInfo.user.userId) ) withCollection(FoodNodeCollection) {collection => collection.insertOne(food).map({ res => val id = res.getInsertedId().asObjectId().getValue() Ok(Json.toJson(food.withId(id))) }).head() }.flatten } catch { case _: JsResultException => Future.successful( BadRequest(s"Could not parse json into a Food node.") ) } } }