<commit_before>package registration.services

import azure.NotificationHubClient.HubResult
import azure.{Tag, Tags, NotificationHubClient, RawWindowsRegistration}
import models._
import play.api.Logger
import providers.Error

import scala.concurrent.{ExecutionContext, Future}
import scalaz.syntax.either._
import scalaz.{-\/, \/, \/-}
import scalaz.std.option.optionSyntax._

class WindowsNotificationRegistrar(hubClient: NotificationHubClient)(implicit ec: ExecutionContext)
  extends NotificationRegistrar {

  val logger = Logger(classOf[WindowsNotificationRegistrar])

  override def register(lastKnownChannelUri: String, registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    findRegistrations(lastKnownChannelUri, registration).flatMap {
      case \/-(Nil) => createRegistration(registration)
      case \/-(azureRegistration :: Nil) => updateRegistration(azureRegistration, registration)
      case \/-(oneRegistration :: moreRegistration) => deleteAndCreate(oneRegistration :: moreRegistration, registration)
      case -\/(e: Error) => Future.successful(e.left)
    }
  }

  def findRegistrations(lastKnownChannelUri: String, registration: Registration): Future[\/[Error, List[azure.RegistrationResponse]]] = {

    def extractResultFromResponse(
      userIdResults: HubResult[List[azure.RegistrationResponse]],
      deviceIdResults: HubResult[List[azure.RegistrationResponse]]
    ): \/[Error, List[azure.RegistrationResponse]] = {
      for {
        userIdRegistrations <- userIdResults
        deviceIdRegistrations <- deviceIdResults
      } yield (deviceIdRegistrations ++ userIdRegistrations).distinct
    }

    for {
      userIdResults <- hubClient.registrationsByTag(Tag.fromUserId(registration.userId).encodedTag)
      deviceIdResults <- hubClient.registrationsByChannelUri(channelUri = lastKnownChannelUri)
    } yield extractResultFromResponse(userIdResults, deviceIdResults)
  }

  private def createRegistration(registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    logger.debug(s"creating registration $registration")
    hubClient.create(RawWindowsRegistration.fromMobileRegistration(registration))
      .map(hubResultToRegistrationResponse)
  }

  private def updateRegistration(azureRegistration: azure.RegistrationResponse, registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    logger.debug(s"updating registration ${azureRegistration.registration} with $registration")
    hubClient.update(azureRegistration.registration, RawWindowsRegistration.fromMobileRegistration(registration))
      .map(hubResultToRegistrationResponse)<commit_msg>typo + private<commit_after>package registration.services

import azure.NotificationHubClient.HubResult
import azure.{Tag, Tags, NotificationHubClient, RawWindowsRegistration}
import models._
import play.api.Logger
import providers.Error

import scala.concurrent.{ExecutionContext, Future}
import scalaz.syntax.either._
import scalaz.{-\/, \/, \/-}
import scalaz.std.option.optionSyntax._

class WindowsNotificationRegistrar(hubClient: NotificationHubClient)(implicit ec: ExecutionContext)
  extends NotificationRegistrar {

  val logger = Logger(classOf[WindowsNotificationRegistrar])

  override def register(lastKnownChannelUri: String, registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    findRegistrations(lastKnownChannelUri, registration).flatMap {
      case \/-(Nil) => createRegistration(registration)
      case \/-(azureRegistration :: Nil) => updateRegistration(azureRegistration, registration)
      case \/-(oneRegistration :: moreRegistrations) => deleteAndCreate(oneRegistration :: moreRegistrations, registration)
      case -\/(e: Error) => Future.successful(e.left)
    }
  }

  private def findRegistrations(lastKnownChannelUri: String, registration: Registration): Future[\/[Error, List[azure.RegistrationResponse]]] = {

    def extractResultFromResponse(
      userIdResults: HubResult[List[azure.RegistrationResponse]],
      deviceIdResults: HubResult[List[azure.RegistrationResponse]]
    ): \/[Error, List[azure.RegistrationResponse]] = {
      for {
        userIdRegistrations <- userIdResults
        deviceIdRegistrations <- deviceIdResults
      } yield (deviceIdRegistrations ++ userIdRegistrations).distinct
    }

    for {
      userIdResults <- hubClient.registrationsByTag(Tag.fromUserId(registration.userId).encodedTag)
      deviceIdResults <- hubClient.registrationsByChannelUri(channelUri = lastKnownChannelUri)
    } yield extractResultFromResponse(userIdResults, deviceIdResults)
  }

  private def createRegistration(registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    logger.debug(s"creating registration $registration")
    hubClient.create(RawWindowsRegistration.fromMobileRegistration(registration))
      .map(hubResultToRegistrationResponse)
  }

  private def updateRegistration(azureRegistration: azure.RegistrationResponse, registration: Registration): Future[\/[Error, RegistrationResponse]] = {
    logger.debug(s"updating registration ${azureRegistration.registration} with $registration")
    hubClient.update(azureRegistration.registration, RawWindowsRegistration.fromMobileRegistration(registration))
      .map(hubResultToRegistrationResponse)
{'fraction_non_alphanumeric': 0.10062299414763073, 'fraction_numerical': 0.0, 'mean_word_length': 5.6893939393939394, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '4742447', 'n_tokens_mistral': 1371, 'n_tokens_neox': 1305, 'n_words': 243}