repository->getUsageStatistics($commandName, $since); } public function getPopularCommands(int $limit = 10, ?DateTimeImmutable $since = null): array { return $this->repository->getPopularCommands($limit, $since); } public function getCommandTrends( string $commandName, Period $period = Period::DAILY, ?DateTimeImmutable $start = null, ?DateTimeImmutable $end = null ): array { $start ??= new DateTimeImmutable('-30 days'); $end ??= new DateTimeImmutable(); return $this->repository->getTrendData($commandName, $period, $start, $end); } public function getAllCommandNames(): array { return $this->repository->getAllCommandNames(); } public function cleanupOldData(int $daysToKeep = 90): int { $cutoffDate = new DateTimeImmutable("-{$daysToKeep} days"); return $this->repository->cleanup($cutoffDate); } public function getOverallStatistics(?DateTimeImmutable $since = null): array { $commands = $this->getAllCommandNames(); $statistics = []; foreach ($commands as $commandName) { $statistics[$commandName] = $this->getCommandStatistics($commandName, $since); } return $statistics; } public function getMostFailingCommands(int $limit = 10, ?DateTimeImmutable $since = null): array { $commands = $this->getAllCommandNames(); $failingCommands = []; foreach ($commands as $commandName) { $stats = $this->getCommandStatistics($commandName, $since); if ($stats->totalExecutions > 0) { $failingCommands[] = [ 'command_name' => $commandName, 'failure_rate' => $stats->getFailureRate(), 'total_executions' => $stats->totalExecutions, 'failed_executions' => $stats->failedExecutions, ]; } } // Sort by failure rate descending usort($failingCommands, function ($a, $b) { return $b['failure_rate']->getValue() <=> $a['failure_rate']->getValue(); }); return array_slice($failingCommands, 0, $limit); } public function getSlowestCommands(int $limit = 10, ?DateTimeImmutable $since = null): array { $commands = $this->getAllCommandNames(); $slowCommands = []; foreach ($commands as $commandName) { $stats = $this->getCommandStatistics($commandName, $since); if ($stats->totalExecutions > 0) { $slowCommands[] = [ 'command_name' => $commandName, 'average_execution_time' => $stats->averageExecutionTime, 'max_execution_time' => $stats->maxExecutionTime, 'total_executions' => $stats->totalExecutions, ]; } } // Sort by average execution time descending usort($slowCommands, function ($a, $b) { return $b['average_execution_time']->toMilliseconds() <=> $a['average_execution_time']->toMilliseconds(); }); return array_slice($slowCommands, 0, $limit); } public function getUsageByHour(?DateTimeImmutable $since = null): array { $commands = $this->getAllCommandNames(); $hourlyUsage = array_fill(0, 24, 0); foreach ($commands as $commandName) { $stats = $this->getCommandStatistics($commandName, $since); if ($stats->hourlyDistribution) { foreach ($stats->hourlyDistribution as $hour => $count) { $hourlyUsage[$hour] += $count; } } } return $hourlyUsage; } public function getCommandHealthScore(string $commandName, ?DateTimeImmutable $since = null): float { $stats = $this->getCommandStatistics($commandName, $since); if ($stats->totalExecutions === 0) { return 0.0; } // Health score based on success rate (70%) and performance (30%) $successScore = $stats->getSuccessRate()->getValue() / 100; // Performance score: inverse of execution time (normalized) $avgTimeMs = $stats->averageExecutionTime->toMilliseconds(); $performanceScore = $avgTimeMs > 0 ? min(1.0, 1000 / $avgTimeMs) : 1.0; return ($successScore * 0.7) + ($performanceScore * 0.3); } }