<commit_before>package pl.newicom.dddd.aggregate

import pl.newicom.dddd.actor.BusinessEntityActorFactory
import pl.newicom.dddd.aggregate.AggregateRootSupport.{Eventually, Immediately}
import pl.newicom.dddd.aggregate.error.AggregateRootNotInitializedException
import pl.newicom.dddd.messaging.command.CommandMessage
import pl.newicom.dddd.messaging.event.EventMessage
import pl.newicom.dddd.office.LocalOfficeId

import scala.concurrent.duration._

abstract class AggregateRootActorFactory[A <: AggregateRoot[_, _, A]: LocalOfficeId] extends BusinessEntityActorFactory[A] {
  def inactivityTimeout: Duration = 1.minute
}

trait AggregateState[S <: AggregateState[S]] {
  type StateMachine = PartialFunction[DomainEvent, S]
  def apply: StateMachine
  def eventHandlerDefined(e: DomainEvent): Boolean = apply.isDefinedAt(e)
  def initialized: Boolean = true
}

trait AggregateBehaviour[E <: DomainEvent, S <: AggregateState[S]] extends AggregateState[S] {
  implicit def toEventually(e: E): Immediately[E] = Immediately(Seq(e))
  type HandleCommand = PartialFunction[Any, Eventually[E]]

  def handleCommand: HandleCommand
}

trait AggregateActions[E <: DomainEvent, S <: AggregateState[S]] extends AggregateBehaviour[E, S] {

  case class Actions(commandHandlers: HandleCommand, eventHandlers: StateMachine) {
    def handleEvents(eh: StateMachine): Actions =
      copy(eventHandlers = eh)

    def ++(other: Actions): Actions =
      Actions(commandHandlers.orElse(other.commandHandlers), eventHandlers.orElse(other.eventHandlers))

    def orElse[SS <: S](other: AggregateActions[E, S], f: SS => S = (a: SS) => a): Actions = {
      Actions(commandHandlers.orElse(other.handleCommand), eventHandlers.orElse(other.apply.asInstanceOf[PartialFunction[DomainEvent, SS]].andThen(f)))
    }

  }

  def handleCommand: HandleCommand =
    actions.commandHandlers

  def apply: StateMachine =
    actions.eventHandlers

  protected def actions: Actions

  protected def handleCommands(hc: HandleCommand) =
    Actions(hc, null)
}

trait Uninitialized[S <: AggregateState[S]] {
  this: AggregateState[S] =>
  override def initialized = false
}

abstract class AggregateRoot[Event <: DomainEvent, S <: AggregateState[S] : Uninitialized, A <: AggregateRoot[Event, S, A] : LocalOfficeId] extends AggregateRootBase with CollaborationSupport[Event] {

  type HandleCommand = PartialFunction[Any, Eventually[Event]]

  override def officeId: LocalOfficeId[A] = implicitly[LocalOfficeId[A]]
  override def department: String = officeId.department

  private lazy val sm = new StateManager(onStateChanged = messageProcessed)

  def initialized: Boolean = state.initialized

  def state: S = sm.state<commit_msg>[AR] Actions.map<commit_after>package pl.newicom.dddd.aggregate

import pl.newicom.dddd.actor.BusinessEntityActorFactory
import pl.newicom.dddd.aggregate.AggregateRootSupport.{Eventually, Immediately}
import pl.newicom.dddd.aggregate.error.AggregateRootNotInitializedException
import pl.newicom.dddd.messaging.command.CommandMessage
import pl.newicom.dddd.messaging.event.EventMessage
import pl.newicom.dddd.office.LocalOfficeId

import scala.concurrent.duration._

abstract class AggregateRootActorFactory[A <: AggregateRoot[_, _, A]: LocalOfficeId] extends BusinessEntityActorFactory[A] {
  def inactivityTimeout: Duration = 1.minute
}

trait AggregateState[S <: AggregateState[S]] {
  type StateMachine = PartialFunction[DomainEvent, S]
  def apply: StateMachine
  def eventHandlerDefined(e: DomainEvent): Boolean = apply.isDefinedAt(e)
  def initialized: Boolean = true
}

trait AggregateBehaviour[E <: DomainEvent, S <: AggregateState[S]] extends AggregateState[S] {
  implicit def toEventually(e: E): Immediately[E] = Immediately(Seq(e))
  type Command = Any
  type HandleCommand = PartialFunction[Command, Eventually[E]]

  def handleCommand: HandleCommand
}

trait AggregateActions[E <: DomainEvent, S <: AggregateState[S]] extends AggregateBehaviour[E, S] {

  case class Actions(commandHandlers: HandleCommand, eventHandlers: StateMachine = null) {
    def handleEvents(eh: StateMachine): Actions =
      copy(eventHandlers = eh)

    def map[SS <: S](f: SS => S): Actions =
      copy(eventHandlers = eventHandlers.asInstanceOf[PartialFunction[DomainEvent, SS]].andThen(f))

    def ++(other: Actions): Actions =
      Actions(
        commandHandlers.orElse(other.commandHandlers),
        eventHandlers.orElse(other.eventHandlers)
      )

    def orElse[SS <: S](other: AggregateActions[E, S], f: SS => S = (a: SS) => a): Actions =
      Actions(
        commandHandlers.orElse(other.handleCommand),
        eventHandlers.orElse(other.apply.asInstanceOf[PartialFunction[DomainEvent, SS]].andThen(f))
      )

  }

  def handleCommand: HandleCommand =
    actions.commandHandlers

  def apply: StateMachine =
    actions.eventHandlers

  protected def actions: Actions

  protected def handleCommands(hc: HandleCommand) =
    Actions(hc)

}

trait Uninitialized[S <: AggregateState[S]] {
  this: AggregateState[S] =>
  override def initialized = false
}

abstract class AggregateRoot[Event <: DomainEvent, S <: AggregateState[S] : Uninitialized, A <: AggregateRoot[Event, S, A] : LocalOfficeId] extends AggregateRootBase with CollaborationSupport[Event] {

  type HandleCommand = PartialFunction[Any, Eventually[Event]]

  override def officeId: LocalOfficeId[A] = implicitly[LocalOfficeId[A]]
  override def department: String = officeId.department

  private lazy val sm = new StateManager(onStateChanged = messageProcessed)

  def initialized: Boolean = state.initialized

  def state: S = sm.state
{'fraction_non_alphanumeric': 0.10315339390700161, 'fraction_numerical': 0.0003563156957063959, 'mean_word_length': 5.430698739977091, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 10, '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': '3142538', 'n_tokens_mistral': 1818, 'n_tokens_neox': 1715, 'n_words': 376}