<commit_before>package com.meetup.iap

import unfiltered.filter.Planify
import unfiltered.request._
import unfiltered.response._
import unfiltered.directives._

import org.json4s.JsonAST.{JString, JInt}
import org.json4s.JsonDSL._
import org.json4s.{DefaultFormats, JValue}
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization.writePretty

import scala.util.Try
import com.meetup.util.Logging
import scala.io.Source
import com.meetup.iap.receipt.{ReceiptRenderer, ReceiptGenerator}

object IAPPlan extends Logging {
  implicit val formats = DefaultFormats

  private def getOrBad[T](opt: Option[T]) = Directives.getOrElse(opt, BadRequest)

  private def getOrgPlanId(json: JValue) = {
    val orgPlanId: Option[Int] =
      json \ "orgPlanId" match {
        case JString(id) => Try(id.toInt).toOption
        case JInt(id) => Some(id.toInt)
        case _ => None
    }

    getOrBad(orgPlanId)
  }

  private def getIntFromString(code: String) = {
    getOrBad(Try(code.toInt).toOption)
  }

  private def getStatusCode(json: JValue) = {
    val statusCode: Option[Int] = 
      json \ "status" match {
        case JString(id) => Try(id.toInt).toOption
        case JInt(id) => Some(id.toInt)
        case _ => None 
      }

    getOrBad(statusCode)
  }

  private def getReceiptData(json: JValue) = {
    val receiptOpt = json \ "receipt-data" match {
      case JString(receipt) => Some(receipt)
      case _ => None
    }

    getOrBad(receiptOpt)
  }

  def plan = Planify { Directive.Intent {
    case GET(Path("/")) => Directives.success(page)

    case GET(Path("/plans")) => Directives.success {
        val json = pretty(render(
          Biller.plans.values.map { plan =>
            ("id" -> plan.getOrgPlanId.toInt) ~
            ("name" -> plan.getName) ~
            ("description" -> plan.getDescription)
        }))

      log.info(s"Serving up ${Biller.plans.size} plans")
      JsonContent ~> ResponseString(json)
    }

    case POST(Path("/subs/clear")) => Directives.success {
      Biller.clearSubs()
      JsonContent ~> Ok
    }

    // curl -d '' http://localhost:9090/receipts/abcd/renew/<statusCode>
    case POST(Path(Seg("subs" :: receiptEncoded :: "renew" :: statusCode :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
        code <- getIntFromString(statusCode)
      } yield {
        Biller.renewSub(sub, code)
        JsonContent ~> Ok
      }

    case POST(Path(Seg("subs" :: receiptEncoded :: "cancel" :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
      } yield {
        Biller.cancelSub(sub)
        JsonContent ~> Ok
      }


    case POST(Path(Seg("subs" :: receiptEncoded :: "refund" :: transactionId :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
        receiptInfo <- getOrBad(sub.transactionMap.get(transactionId))
      } yield {
        Biller.refundTransaction(sub, receiptInfo)
        JsonContent ~> Ok
      }


    case GET(Path("/subs")) => Directives.success {
      val sortedSubs =
        Biller.subscriptions.values
          .toList
          .sortBy(_.originalReceipt.purchaseDate.getTime)
          .reverse

      JsonContent ~> ResponseString(writePretty(sortedSubs))<commit_msg>return 204 for successful refunds<commit_after>package com.meetup.iap

import unfiltered.filter.Planify
import unfiltered.request._
import unfiltered.response._
import unfiltered.directives._

import org.json4s.JsonAST.{JString, JInt}
import org.json4s.JsonDSL._
import org.json4s.{DefaultFormats, JValue}
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization.writePretty

import scala.util.Try
import com.meetup.util.Logging
import scala.io.Source
import com.meetup.iap.receipt.{ReceiptRenderer, ReceiptGenerator}

object IAPPlan extends Logging {
  implicit val formats = DefaultFormats

  private def getOrBad[T](opt: Option[T]) = Directives.getOrElse(opt, BadRequest)

  private def getOrgPlanId(json: JValue) = {
    val orgPlanId: Option[Int] =
      json \ "orgPlanId" match {
        case JString(id) => Try(id.toInt).toOption
        case JInt(id) => Some(id.toInt)
        case _ => None
    }

    getOrBad(orgPlanId)
  }

  private def getIntFromString(code: String) = {
    getOrBad(Try(code.toInt).toOption)
  }

  private def getStatusCode(json: JValue) = {
    val statusCode: Option[Int] = 
      json \ "status" match {
        case JString(id) => Try(id.toInt).toOption
        case JInt(id) => Some(id.toInt)
        case _ => None 
      }

    getOrBad(statusCode)
  }

  private def getReceiptData(json: JValue) = {
    val receiptOpt = json \ "receipt-data" match {
      case JString(receipt) => Some(receipt)
      case _ => None
    }

    getOrBad(receiptOpt)
  }

  def plan = Planify { Directive.Intent {
    case GET(Path("/")) => Directives.success(page)

    case GET(Path("/plans")) => Directives.success {
        val json = pretty(render(
          Biller.plans.values.map { plan =>
            ("id" -> plan.getOrgPlanId.toInt) ~
            ("name" -> plan.getName) ~
            ("description" -> plan.getDescription)
        }))

      log.info(s"Serving up ${Biller.plans.size} plans")
      JsonContent ~> ResponseString(json)
    }

    case POST(Path("/subs/clear")) => Directives.success {
      Biller.clearSubs()
      JsonContent ~> Ok
    }

    // curl -d '' http://localhost:9090/receipts/abcd/renew/<statusCode>
    case POST(Path(Seg("subs" :: receiptEncoded :: "renew" :: statusCode :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
        code <- getIntFromString(statusCode)
      } yield {
        Biller.renewSub(sub, code)
        JsonContent ~> Ok
      }

    case POST(Path(Seg("subs" :: receiptEncoded :: "cancel" :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
      } yield {
        Biller.cancelSub(sub)
        JsonContent ~> Ok
      }


    case POST(Path(Seg("subs" :: receiptEncoded :: "refund" :: transactionId :: Nil))) =>
      for {
        sub <- getOrBad(Biller.subscriptions.get(receiptEncoded))
        receiptInfo <- getOrBad(sub.transactionMap.get(transactionId))
      } yield {
        Biller.refundTransaction(sub, receiptInfo)
        NoContent ~> Ok
      }


    case GET(Path("/subs")) => Directives.success {
      val sortedSubs =
        Biller.subscriptions.values
          .toList
          .sortBy(_.originalReceipt.purchaseDate.getTime)
          .reverse

      JsonContent ~> ResponseString(writePretty(sortedSubs))
{'fraction_non_alphanumeric': 0.1291490645745323, 'fraction_numerical': 0.003168376584188292, 'mean_word_length': 2.7643384440658716, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 55, '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': '4430552', 'n_tokens_mistral': 2267, 'n_tokens_neox': 2127, 'n_words': 391}