<commit_before>package gu.msnotifications

import gu.msnotifications.HubFailure.{HubParseFailed, HubServiceError}
import play.api.libs.ws.{WSClient, WSResponse}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import scalaz.\/
import scalaz.std.option.optionSyntax._

case class NotificationHubError(message: String)

object NotificationHubClient {
  type HubResult[T] = HubFailure \/ T
}
/**
 * https://msdn.microsoft.com/en-us/library/azure/dn223264.aspx
 */
final class NotificationHubClient(notificationHubConnection: NotificationHubConnection, wsClient: WSClient)
                                 (implicit executionContext: ExecutionContext) {

  import notificationHubConnection._
  import NotificationHubClient.HubResult

  def post(uri: String, data: scala.xml.Elem, headers: List[(String, String)] = Nil) = {
    wsClient
      .url(uri)
      .withHeaders("Authorization" -> authorizationHeader(uri))
      .withHeaders(headers: _*)
      .post(data)
  }

  def get(uri: String, headers: List[(String, String)] = Nil) = {
    wsClient
      .url(uri)
      .withHeaders("Authorization" -> authorizationHeader(uri))
      .withHeaders(headers: _*)
      .get()
  }

  def register(rawWindowsRegistration: RawWindowsRegistration): Future[HubResult[RegistrationId]] = {
    post(
      uri = s"""$notificationsHubUrl/registrations/?api-version=2015-01""",
      data = rawWindowsRegistration.toXml
    ).map(processRegistrationResponse)
  }

  def update(registrationId: RegistrationId,
             rawWindowsRegistration: RawWindowsRegistration
              ): Future[HubResult[RegistrationId]] = {
    post(
      uri = s"""$notificationsHubUrl/registration/${registrationId.registrationId}?api-version=2015-01""",
      data = rawWindowsRegistration.toXml
    ).map(processRegistrationResponse)
  }

  def sendPush(azureWindowsPush: AzureXmlPush): Future[HubResult[Unit]] = {
    val serviceBusTags = azureWindowsPush.tagQuery.map(tagQuery => "ServiceBusNotification-Tags" -> tagQuery).toList

    post(
      uri = s"""$notificationsHubUrl/messages/?api-version=2015-01""",
      data = azureWindowsPush.xml,
      headers = ("X-WNS-Type" -> azureWindowsPush.wnsType) ::
        ("ServiceBusNotification-Format" -> "windows") ::
        serviceBusTags
    ).map(processResponse).map(_.map(_ => ()))
  }

  /**
   * This is used for health-checking only: return the title of the feed,
   * which is expected to be 'Registrations'.
   * @return the title of the feed if it succeeds getting one
   */
  def fetchRegistrationsListEndpoint: Future[HubResult[String]] = {
    get(s"""$notificationsHubUrl/registrations/?api-version=2015-01""")
      .map(processResponse)
      .map(_.map(xml => (xml \ "title").text))
  }

  private def processResponse(response: WSResponse): HubResult[scala.xml.Elem] = {
    Try(response.xml).toOption.toRightDisjunction {
      if (response.status != 200)<commit_msg>Replace post/get method with generic "request" method<commit_after>package gu.msnotifications

import gu.msnotifications.HubFailure.{HubParseFailed, HubServiceError}
import play.api.libs.ws.{WSClient, WSResponse}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import scalaz.\/
import scalaz.std.option.optionSyntax._

case class NotificationHubError(message: String)

object NotificationHubClient {
  type HubResult[T] = HubFailure \/ T
}
/**
 * https://msdn.microsoft.com/en-us/library/azure/dn223264.aspx
 */
final class NotificationHubClient(notificationHubConnection: NotificationHubConnection, wsClient: WSClient)
                                 (implicit executionContext: ExecutionContext) {

  import notificationHubConnection._
  import NotificationHubClient.HubResult

  private def request(uri: String) = wsClient
    .url(uri)
    .withHeaders("Authorization" -> authorizationHeader(uri))

  def register(rawWindowsRegistration: RawWindowsRegistration): Future[HubResult[RegistrationId]] = {
    request(s"$notificationsHubUrl/registrations/?api-version=2015-01")
      .post(rawWindowsRegistration.toXml)
      .map(processRegistrationResponse)
  }

  def update(registrationId: RegistrationId,
             rawWindowsRegistration: RawWindowsRegistration
              ): Future[HubResult[RegistrationId]] = {
    request(s"$notificationsHubUrl/registration/${registrationId.registrationId}?api-version=2015-01")
      .post(rawWindowsRegistration.toXml)
      .map(processRegistrationResponse)
  }

  def sendPush(azureWindowsPush: AzureXmlPush): Future[HubResult[Unit]] = {
    val serviceBusTags = azureWindowsPush.tagQuery.map(tagQuery => "ServiceBusNotification-Tags" -> tagQuery).toList

    request(s"$notificationsHubUrl/messages/?api-version=2015-01")
      .withHeaders("X-WNS-Type" -> azureWindowsPush.wnsType)
      .withHeaders("ServiceBusNotification-Format" -> "windows")
      .withHeaders(serviceBusTags: _*)
      .post(azureWindowsPush.xml)
      .map(processResponse).map(_.map(_ => ()))
  }

  /**
   * This is used for health-checking only: return the title of the feed,
   * which is expected to be 'Registrations'.
   * @return the title of the feed if it succeeds getting one
   */
  def fetchRegistrationsListEndpoint: Future[HubResult[String]] = {
    request(s"$notificationsHubUrl/registrations/?api-version=2015-01")
      .get()
      .map(processResponse)
      .map(_.map(xml => (xml \ "title").text))
  }

  private def processResponse(response: WSResponse): HubResult[scala.xml.Elem] = {
    Try(response.xml).toOption.toRightDisjunction {
      if (response.status != 200)
{'fraction_non_alphanumeric': 0.12047977085571071, 'fraction_numerical': 0.011815252416756176, 'mean_word_length': 4.069872958257713, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 11}, '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': '6000676', 'n_tokens_mistral': 1703, 'n_tokens_neox': 1589, 'n_words': 292}