<commit_before>package hmda.persistence.submission

import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorContext, ActorRef, Behavior}
import akka.persistence.typed.PersistenceId
import akka.persistence.typed.scaladsl.{Effect, PersistentBehavior}
import akka.persistence.typed.scaladsl.PersistentBehavior.CommandHandler
import hmda.model.edits.EditDetail
import hmda.persistence.HmdaTypedPersistentActor
import akka.actor
import hmda.model.filing.submission.SubmissionId
import hmda.model.filing.submissions.PaginatedResource
import akka.actor.typed.scaladsl.adapter._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import hmda.query.HmdaQuery._

import scala.concurrent.Future

trait EditDetailPersistenceCommand

case class PersistEditDetail(editDetail: EditDetail,
                             replyTo: ActorRef[EditDetailPersistenceEvent])
    extends EditDetailPersistenceCommand

case class GetEditDetails(submissionId: SubmissionId,
                          editName: String,
                          page: Int,
                          replyTo: ActorRef[Future[Seq[EditDetail]]])
    extends EditDetailPersistenceCommand

trait EditDetailPersistenceEvent

case class EditDetailAdded(editDetail: EditDetail)
    extends EditDetailPersistenceEvent

case class EditDetailPersistenceState(
    totalErrorMap: Map[String, Int] = Map.empty)

object EditDetailPersistence
    extends HmdaTypedPersistentActor[EditDetailPersistenceCommand,
                                     EditDetailPersistenceEvent,
                                     EditDetailPersistenceState] {

  override val name: String = "EditDetail"

  override def behavior(
      entityId: String): Behavior[EditDetailPersistenceCommand] = {
    Behaviors.setup { ctx =>
      PersistentBehavior(
        persistenceId = PersistenceId(entityId),
        emptyState = EditDetailPersistenceState(),
        commandHandler = commandHandler(ctx),
        eventHandler = eventHandler
      )
    }
  }

  override def commandHandler(ctx: ActorContext[EditDetailPersistenceCommand])
    : CommandHandler[EditDetailPersistenceCommand,
                     EditDetailPersistenceEvent,
                     EditDetailPersistenceState] = { (state, cmd) =>
    val log = ctx.asScala.log
    cmd match {
      case PersistEditDetail(editDetail, replyTo) =>
        val evt = EditDetailAdded(editDetail)
        Effect.persist(evt).thenRun { _ =>
          log.debug(s"Persisted: $evt")
          replyTo ! evt
        }

      case GetEditDetails(submissionId, editName, page, replyTo) =>
        implicit val untypedSystem: actor.ActorSystem =
          ctx.asScala.system.toUntyped
        implicit val materializer: ActorMaterializer = ActorMaterializer()
        val totalRowCount = state.totalErrorMap.getOrElse(editName, 0)
        val p = PaginatedResource(totalRowCount)(page)
        val persistenceId = s"${EditDetailPersistence.name}-$submissionId"
        val editDetailSource = eventEnvelopeByPersistenceId(persistenceId)
          .drop(p.fromIndex)
          .take(p.toIndex)
          .map(envelope =>
            envelope.event.asInstanceOf[EditDetailPersistenceEvent])
          .collect {<commit_msg>Add TODO warning comment<commit_after>package hmda.persistence.submission

import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorContext, ActorRef, Behavior}
import akka.persistence.typed.PersistenceId
import akka.persistence.typed.scaladsl.{Effect, PersistentBehavior}
import akka.persistence.typed.scaladsl.PersistentBehavior.CommandHandler
import hmda.model.edits.EditDetail
import hmda.persistence.HmdaTypedPersistentActor
import akka.actor
import hmda.model.filing.submission.SubmissionId
import hmda.model.filing.submissions.PaginatedResource
import akka.actor.typed.scaladsl.adapter._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import hmda.query.HmdaQuery._

import scala.concurrent.Future

trait EditDetailPersistenceCommand

case class PersistEditDetail(editDetail: EditDetail,
                             replyTo: ActorRef[EditDetailPersistenceEvent])
    extends EditDetailPersistenceCommand

case class GetEditDetails(submissionId: SubmissionId,
                          editName: String,
                          page: Int,
                          replyTo: ActorRef[Future[Seq[EditDetail]]])
    extends EditDetailPersistenceCommand

trait EditDetailPersistenceEvent

case class EditDetailAdded(editDetail: EditDetail)
    extends EditDetailPersistenceEvent

case class EditDetailPersistenceState(
    totalErrorMap: Map[String, Int] = Map.empty)

object EditDetailPersistence
    extends HmdaTypedPersistentActor[EditDetailPersistenceCommand,
                                     EditDetailPersistenceEvent,
                                     EditDetailPersistenceState] {

  override val name: String = "EditDetail"

  override def behavior(
      entityId: String): Behavior[EditDetailPersistenceCommand] = {
    Behaviors.setup { ctx =>
      PersistentBehavior(
        persistenceId = PersistenceId(entityId),
        emptyState = EditDetailPersistenceState(),
        commandHandler = commandHandler(ctx),
        eventHandler = eventHandler
      )
    }
  }

  override def commandHandler(ctx: ActorContext[EditDetailPersistenceCommand])
    : CommandHandler[EditDetailPersistenceCommand,
                     EditDetailPersistenceEvent,
                     EditDetailPersistenceState] = { (state, cmd) =>
    val log = ctx.asScala.log
    cmd match {
      case PersistEditDetail(editDetail, replyTo) =>
        val evt = EditDetailAdded(editDetail)
        Effect.persist(evt).thenRun { _ =>
          log.debug(s"Persisted: $evt")
          replyTo ! evt
        }

      //TODO: this won't work, would require serializing a Future with protobuf. Execute stream in the web layer instead
      case GetEditDetails(submissionId, editName, page, replyTo) =>
        implicit val untypedSystem: actor.ActorSystem =
          ctx.asScala.system.toUntyped
        implicit val materializer: ActorMaterializer = ActorMaterializer()
        val totalRowCount = state.totalErrorMap.getOrElse(editName, 0)
        val p = PaginatedResource(totalRowCount)(page)
        val persistenceId = s"${EditDetailPersistence.name}-$submissionId"
        val editDetailSource = eventEnvelopeByPersistenceId(persistenceId)
          .drop(p.fromIndex)
          .take(p.toIndex)
          .map(envelope =>
            envelope.event.asInstanceOf[EditDetailPersistenceEvent])
          .collect {
{'fraction_non_alphanumeric': 0.07242848447961046, 'fraction_numerical': 0.00030432136335970786, 'mean_word_length': 3.2053742802303264, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4743020', 'n_tokens_mistral': 1802, 'n_tokens_neox': 1802, 'n_words': 337}