<commit_before>
# ============== INTEGRATION SETUP =============== #
class CustomerApp extends Space.Application

  RequiredModules: ['Space.cqrs']

  Dependencies:
    commandBus: 'Space.messaging.CommandBus'
    eventBus: 'Space.messaging.EventBus'
    configuration: 'Space.cqrs.Configuration'
    Mongo: 'Mongo'

  configure: ->
    super
    @configuration.useInMemoryCollections = true
    @injector.map('CustomerRegistrations').to new @Mongo.Collection(null)
    @injector.map(CustomerRegistrationRouter).asSingleton()
    @injector.map(CustomerRouter).asSingleton()
    @injector.map(EmailRouter).asSingleton()
    @injector.map(CustomerRegistrationViewModel).asSingleton()

  run: ->
    super
    @commits = @injector.get 'Space.cqrs.Commits'
    @resetDatabase()
    @injector.create CustomerRegistrationRouter
    @injector.create CustomerRouter
    @injector.create EmailRouter
    @injector.create CustomerRegistrationViewModel

  sendCommand: -> @commandBus.send.apply @commandBus, arguments

  subscribeTo: -> @eventBus.subscribeTo.apply @eventBus, arguments

  resetDatabase: -> @commits.remove {}

# -------------- COMMANDS ---------------

class CustomerApp.RegisterCustomer extends Space.messaging.Command
  @type 'CustomerApp.RegisterCustomer'
  constructor: (data) ->
    { @registrationId, @customerId, @version, @customerName } = data

class CustomerApp.CreateCustomer extends Space.messaging.Command
  @type 'CustomerApp.CreateCustomer'
  constructor: (data) -> { @customerId, @version, @name } = data

class CustomerApp.SendWelcomeEmail extends Space.messaging.Command
  @type 'CustomerApp.SendWelcomeEmail'
  constructor: (data) -> { @customerId, @version, @customerName } = data

# --------------- EVENTS ---------------

class CustomerApp.RegistrationInitiated extends Space.messaging.Event
  @type 'CustomerApp.RegistrationInitiated'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String
    customerName: String

class CustomerApp.CustomerCreated extends Space.messaging.Event
  @type 'CustomerApp.CustomerCreated'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerName: String

class CustomerApp.WelcomeEmailTriggered extends Space.messaging.Event
  @type 'CustomerApp.WelcomeEmailTriggered'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String

class CustomerApp.WelcomeEmailSent extends Space.messaging.Event
  @type 'CustomerApp.WelcomeEmailSent'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String
    email: String

class CustomerApp.RegistrationCompleted extends Space.messaging.Event
  @type 'CustomerApp.RegistrationCompleted'

# -------------- AGGREGATES ---------------

class Customer extends Space.cqrs.Aggregate

  _name: null

  initialize: (id, data) ->

    @record new CustomerApp.CustomerCreated
      sourceId: id
      customerName: data.name

  @handle CustomerApp.CustomerCreated, (event) -> @_name = event.customerName

# -------------- SAGAS ---------------

class CustomerRegistration extends Space.cqrs.ProcessManager

  _customerId: null
  _customerName: null

  @STATES:
    creatingCustomer: 0
    sendingWelcomeEmail: 1
    completed: 2

  initialize: (id, data) ->

    @trigger new CustomerApp.CreateCustomer
      customerId: data.customerId
      name: data.customerName

    @record new CustomerApp.RegistrationInitiated
      sourceId: id
      customerId: data.customerId
      customerName: data.customerName

  onCustomerCreated: (event) ->

    @trigger new CustomerApp.SendWelcomeEmail
      customerId: @_customerId
      customerName: @_customerName

    @record new CustomerApp.WelcomeEmailTriggered
      sourceId: @getId()
      customerId: @_customerId

  onWelcomeEmailSent: (event) ->
    @record new CustomerApp.RegistrationCompleted sourceId: @getId()

  @handle CustomerApp.RegistrationInitiated, (event) ->
    @_customerId = event.customerId
    @_customerName = event.customerName
    @_state = CustomerRegistration.STATES.creatingCustomer

  @handle CustomerApp.WelcomeEmailTriggered, ->
    @_state = CustomerRegistration.STATES.sendingWelcomeEmail

  @handle CustomerApp.RegistrationCompleted, ->
    @_state = CustomerRegistration.STATES.completed

# -------------- ROUTERS --------------- #

class CustomerRegistrationRouter extends Space.messaging.Controller

  @toString: -> 'CustomerRegistrationRouter'

  Dependencies:
    repository: 'Space.cqrs.Repository'
    registrations: 'CustomerRegistrations'

  @handle CustomerApp.RegisterCustomer, on: (event) ->

    registration = new CustomerRegistration event.registrationId, event
    @repository.save registration, registration.getVersion()

  @handle CustomerApp.CustomerCreated, on: (event) ->

    registrationId = @registrations.findOne(customerId: event.sourceId)._id
    registration = @repository.find CustomerRegistration, registrationId
    registration.onCustomerCreated event
    @repository.save registration, registration.getVersion()

  @handle CustomerApp.WelcomeEmailSent, on: (event) ->

    registrationId = @registrations.findOne(customerId: event.customerId)._id
    registration = @repository.find CustomerRegistration, registrationId
    registration.onWelcomeEmailSent()
    @repository.save registration, registration.getVersion()


class CustomerRouter extends Space.messaging.Controller

  @toString: -> 'CustomerRouter'

  Dependencies:
    repository: 'Space.cqrs.Repository'

  @handle CustomerApp.CreateCustomer, on: (command) ->

    customer = new Customer command.customerId, command<commit_msg>Renamed command handler parameter from 'event' to 'command'<commit_after>
# ============== INTEGRATION SETUP =============== #
class CustomerApp extends Space.Application

  RequiredModules: ['Space.cqrs']

  Dependencies:
    commandBus: 'Space.messaging.CommandBus'
    eventBus: 'Space.messaging.EventBus'
    configuration: 'Space.cqrs.Configuration'
    Mongo: 'Mongo'

  configure: ->
    super
    @configuration.useInMemoryCollections = true
    @injector.map('CustomerRegistrations').to new @Mongo.Collection(null)
    @injector.map(CustomerRegistrationRouter).asSingleton()
    @injector.map(CustomerRouter).asSingleton()
    @injector.map(EmailRouter).asSingleton()
    @injector.map(CustomerRegistrationViewModel).asSingleton()

  run: ->
    super
    @commits = @injector.get 'Space.cqrs.Commits'
    @resetDatabase()
    @injector.create CustomerRegistrationRouter
    @injector.create CustomerRouter
    @injector.create EmailRouter
    @injector.create CustomerRegistrationViewModel

  sendCommand: -> @commandBus.send.apply @commandBus, arguments

  subscribeTo: -> @eventBus.subscribeTo.apply @eventBus, arguments

  resetDatabase: -> @commits.remove {}

# -------------- COMMANDS ---------------

class CustomerApp.RegisterCustomer extends Space.messaging.Command
  @type 'CustomerApp.RegisterCustomer'
  constructor: (data) ->
    { @registrationId, @customerId, @version, @customerName } = data

class CustomerApp.CreateCustomer extends Space.messaging.Command
  @type 'CustomerApp.CreateCustomer'
  constructor: (data) -> { @customerId, @version, @name } = data

class CustomerApp.SendWelcomeEmail extends Space.messaging.Command
  @type 'CustomerApp.SendWelcomeEmail'
  constructor: (data) -> { @customerId, @version, @customerName } = data

# --------------- EVENTS ---------------

class CustomerApp.RegistrationInitiated extends Space.messaging.Event
  @type 'CustomerApp.RegistrationInitiated'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String
    customerName: String

class CustomerApp.CustomerCreated extends Space.messaging.Event
  @type 'CustomerApp.CustomerCreated'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerName: String

class CustomerApp.WelcomeEmailTriggered extends Space.messaging.Event
  @type 'CustomerApp.WelcomeEmailTriggered'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String

class CustomerApp.WelcomeEmailSent extends Space.messaging.Event
  @type 'CustomerApp.WelcomeEmailSent'
  @fields:
    sourceId: String
    version: Match.Optional(Match.Integer)
    customerId: String
    email: String

class CustomerApp.RegistrationCompleted extends Space.messaging.Event
  @type 'CustomerApp.RegistrationCompleted'

# -------------- AGGREGATES ---------------

class Customer extends Space.cqrs.Aggregate

  _name: null

  initialize: (id, data) ->

    @record new CustomerApp.CustomerCreated
      sourceId: id
      customerName: data.name

  @handle CustomerApp.CustomerCreated, (event) -> @_name = event.customerName

# -------------- SAGAS ---------------

class CustomerRegistration extends Space.cqrs.ProcessManager

  _customerId: null
  _customerName: null

  @STATES:
    creatingCustomer: 0
    sendingWelcomeEmail: 1
    completed: 2

  initialize: (id, data) ->

    @trigger new CustomerApp.CreateCustomer
      customerId: data.customerId
      name: data.customerName

    @record new CustomerApp.RegistrationInitiated
      sourceId: id
      customerId: data.customerId
      customerName: data.customerName

  onCustomerCreated: (event) ->

    @trigger new CustomerApp.SendWelcomeEmail
      customerId: @_customerId
      customerName: @_customerName

    @record new CustomerApp.WelcomeEmailTriggered
      sourceId: @getId()
      customerId: @_customerId

  onWelcomeEmailSent: (event) ->
    @record new CustomerApp.RegistrationCompleted sourceId: @getId()

  @handle CustomerApp.RegistrationInitiated, (event) ->
    @_customerId = event.customerId
    @_customerName = event.customerName
    @_state = CustomerRegistration.STATES.creatingCustomer

  @handle CustomerApp.WelcomeEmailTriggered, ->
    @_state = CustomerRegistration.STATES.sendingWelcomeEmail

  @handle CustomerApp.RegistrationCompleted, ->
    @_state = CustomerRegistration.STATES.completed

# -------------- ROUTERS --------------- #

class CustomerRegistrationRouter extends Space.messaging.Controller

  @toString: -> 'CustomerRegistrationRouter'

  Dependencies:
    repository: 'Space.cqrs.Repository'
    registrations: 'CustomerRegistrations'

  @handle CustomerApp.RegisterCustomer, on: (command) ->

    registration = new CustomerRegistration command.registrationId, command
    @repository.save registration, registration.getVersion()

  @handle CustomerApp.CustomerCreated, on: (event) ->

    registrationId = @registrations.findOne(customerId: event.sourceId)._id
    registration = @repository.find CustomerRegistration, registrationId
    registration.onCustomerCreated event
    @repository.save registration, registration.getVersion()

  @handle CustomerApp.WelcomeEmailSent, on: (event) ->

    registrationId = @registrations.findOne(customerId: event.customerId)._id
    registration = @repository.find CustomerRegistration, registrationId
    registration.onWelcomeEmailSent()
    @repository.save registration, registration.getVersion()


class CustomerRouter extends Space.messaging.Controller

  @toString: -> 'CustomerRouter'

  Dependencies:
    repository: 'Space.cqrs.Repository'

  @handle CustomerApp.CreateCustomer, on: (command) ->

    customer = new Customer command.customerId, command
{'fraction_non_alphanumeric': 0.11827956989247312, 'fraction_numerical': 0.0005288207297726071, 'mean_word_length': 3.985500878734622, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 47, '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': '5922388', 'n_tokens_mistral': 3134, 'n_tokens_neox': 3006, 'n_words': 654}