modules/FeedProcessor/AuditLog/Event.psm1

using module '..\..\Enums.psm1'
using module '..\..\Helper\ObjectHelper.psm1'
using module '..\..\Helper\DateTimeHelper.psm1'
using module '.\Market.psm1'
using module '.\Event\Score.psm1'
using module '.\Event\SportData.psm1'
using module '.\Event\Statistics.psm1'

class Event {

    [string] $id
    [string] $startDate
    [string] $liveCoverage
    [string] $name
    [string] $action #TODO move action to the message
    [string] $status

    [Score] $scoreDetails
    [SportData] $sportData

    [Market[]] $markets
    [hashtable] $info
    [hashtable] $other

    [Statistics] $marketsStatistic

    [bool] $isForced

    Event(){
        $this.markets = @()
        $this.info = @{}
        $this.other = @{}
    }

    Event([string] $id, [datetime] $startDate, [string] $liveCoverage, [string] $name, [string] $action, [string] $status) {
        $this.Event()

        $this.id = $id
        $this.name = $name
        $this.action = $action
        $this.status = $status
        $this.startDate = $startDate
        $this.liveCoverage = $liveCoverage
    }

    [Market] FindMarket([string] $id, [hashtable] $specifiers){
        foreach ($m in $this.markets) {
            if ($m.id -eq $id -and [ObjectHelper]::isEqualHashTable($this.specifiers, $specifiers)){
                return $m
            }
        }

        return $null
    }

    [void] Aggregate([Event] $e){
        if ($null -ne $e) {
            if (-not $this.startDate) { $this.startDate = $e.startDate }
            if (-not $this.liveCoverage) { $this.liveCoverage = $e.liveCoverage }
            if (-not $this.action) { $this.action = $e.action }
            if (-not $this.status) { $this.status = $e.status }

            $this.isForced = ($this.markets.Count -eq 0)

            $this.other = [ObjectHelper]::MergeHashtables($this.other, $e.other)
            $this.markets = [ObjectHelper]::MergeObjectArray($this.markets, $e.markets, 'id')

            foreach ($market in $this.markets) {
                if ($this.isForced) { $market.status = $e.status }
                $market.Aggregate($e.FindMarket($market.id, $market.specifiers))
            }
        }
    }

    [void] CalculateStatistics([Event] $eventItem){
        $this.marketsStatistic = [Statistics]::new()

        foreach ($market in $this.markets) {
            $prevMarket = $eventItem.FindMarket($market.id, $market.specifiers)
            if (-not $prevMarket) {
                $this.marketsStatistic.new += 1
            }
            else {
                if ($market.Equal($prevMarket, $true)) {
                    $this.marketsStatistic.equal += 1
                }
                else {
                    $this.marketsStatistic.modified += 1
                }
            }
        }
    }

    [Event] Copy(){
        $eventItem = [Event]::new()

        $eventItem.id = $this.id
        $eventItem.startDate = $this.startDate
        $eventItem.liveCoverage = $this.liveCoverage
        $eventItem.name = $this.name
        $eventItem.action = $this.action
        $eventItem.status = $this.status

        foreach ($m in $this.markets) {
            $eventItem.markets += $m.Copy()
        }
        if ($this.scoreDetails) { $eventItem.scoreDetails = $this.scoreDetails.Copy() }
        if ($this.sportData) { $eventItem.sportData = $this.sportData.Copy() }

        $eventItem.info = $this.info
        $eventItem.other = $this.other

        return $eventItem
    }
}