<commit_before>package com.ubirch.avatar.core.avatar

import java.util.UUID

import com.typesafe.scalalogging.slf4j.StrictLogging

import com.ubirch.avatar.config.Config
import com.ubirch.avatar.model.db.device.{AvatarState, Device}
import com.ubirch.util.json.{Json4sUtil, JsonFormats}
import com.ubirch.util.mongo.connection.MongoUtil
import com.ubirch.util.mongo.format.MongoFormats
import com.ubirch.util.uuid.UUIDUtil

import org.joda.time.DateTime
import org.json4s.JValue
import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.write

import reactivemongo.bson.{BSONDocumentReader, BSONDocumentWriter, Macros, document}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

/**
  * author: cvandrei
  * since: 2017-02-24
  */
object AvatarStateManager extends MongoFormats
  with StrictLogging {

  private implicit val formats = JsonFormats.default

  private val collectionName = Config.mongoCollectionAvatarState

  implicit protected def avatarStateWriter: BSONDocumentWriter[AvatarState] = Macros.writer[AvatarState]

  implicit protected def avatarStateReader: BSONDocumentReader[AvatarState] = Macros.reader[AvatarState]

  /**
    * Search an [[AvatarState]] based on the id of it's device.
    *
    * @param deviceId deviceId to search with
    * @return None if nothing was found
    */
  def byDeviceId(deviceId: String)(implicit mongo: MongoUtil): Future[Option[AvatarState]] = {

    logger.debug(s"query byDeviceId: deviceId=$deviceId")
    val selector = document("deviceId" -> deviceId)

    mongo.collection(collectionName) flatMap {
      _.find(selector).one[AvatarState]
    }

  }

  /**
    * Create a [[AvatarState]].
    *
    * @param avatarState object to store
    * @return stored entity; None if something went wrong or entity already exists
    */
  def create(avatarState: AvatarState)(implicit mongo: MongoUtil): Future[Option[AvatarState]] = {

    byDeviceId(avatarState.deviceId.toString) flatMap {

      case Some(_: AvatarState) =>

        logger.error(s"unable to create avatarState for deviceId=${avatarState.deviceId}")
        Future(None)

      case None =>

        mongo.collection(collectionName) flatMap { collection =>

          collection.insert[AvatarState](avatarState) map { writeResult =>

            if (writeResult.ok && writeResult.n == 1) {
              logger.debug(s"created new avatarState: $avatarState")
              Some(avatarState)
            } else {
              logger.error("failed to create user")
              None
            }

          }

        }

    }

  }

  /**<commit_msg>UBI-263: optimized imports and improved log messages<commit_after>package com.ubirch.avatar.core.avatar

import com.typesafe.scalalogging.slf4j.StrictLogging

import com.ubirch.avatar.config.Config
import com.ubirch.avatar.model.db.device.{AvatarState, Device}
import com.ubirch.util.json.{Json4sUtil, JsonFormats}
import com.ubirch.util.mongo.connection.MongoUtil
import com.ubirch.util.mongo.format.MongoFormats

import org.joda.time.DateTime
import org.json4s.JValue
import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.write

import reactivemongo.bson.{BSONDocumentReader, BSONDocumentWriter, Macros, document}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

/**
  * author: cvandrei
  * since: 2017-02-24
  */
object AvatarStateManager extends MongoFormats
  with StrictLogging {

  private implicit val formats = JsonFormats.default

  private val collectionName = Config.mongoCollectionAvatarState

  implicit protected def avatarStateWriter: BSONDocumentWriter[AvatarState] = Macros.writer[AvatarState]

  implicit protected def avatarStateReader: BSONDocumentReader[AvatarState] = Macros.reader[AvatarState]

  /**
    * Search an [[AvatarState]] based on the id of it's device.
    *
    * @param deviceId deviceId to search with
    * @return None if nothing was found
    */
  def byDeviceId(deviceId: String)(implicit mongo: MongoUtil): Future[Option[AvatarState]] = {

    logger.debug(s"query byDeviceId: deviceId=$deviceId")
    val selector = document("deviceId" -> deviceId)

    mongo.collection(collectionName) flatMap {
      _.find(selector).one[AvatarState]
    }

  }

  /**
    * Create a [[AvatarState]].
    *
    * @param avatarState object to store
    * @return stored entity; None if something went wrong or entity already exists
    */
  def create(avatarState: AvatarState)(implicit mongo: MongoUtil): Future[Option[AvatarState]] = {

    byDeviceId(avatarState.deviceId.toString) flatMap {

      case Some(_: AvatarState) =>

        logger.error(s"unable to create avatarState (as it already exists) for deviceId=${avatarState.deviceId}")
        Future(None)

      case None =>

        mongo.collection(collectionName) flatMap { collection =>

          collection.insert[AvatarState](avatarState) map { writeResult =>

            if (writeResult.ok && writeResult.n == 1) {
              logger.debug(s"created new avatarState: $avatarState")
              Some(avatarState)
            } else {
              logger.error("failed to create avatarState")
              None
            }

          }

        }

    }

  }

  /**
{'fraction_non_alphanumeric': 0.09865300701954088, 'fraction_numerical': 0.005881236956934168, 'mean_word_length': 3.4868085106382978, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3635566', 'n_tokens_mistral': 1654, 'n_tokens_neox': 1581, 'n_words': 340}