false, 'cache_hit' => false, 'generated_at' => null ); public function __construct( DetectorRegistry $registry, ?RelationshipResolver $resolver = null, ?\MazlanHalim\IntelliLanz\Health\HealthEvaluator $health = null, ?SnapshotCache $cache = null ) { $this->registry = $registry; $this->resolver = $resolver; $this->health = $health; $this->cache = $cache; $this->lastBuildInfo['cache_enabled'] = $cache !== null; } public function build( bool $refresh = false ): Graph { if ( $this->cache !== null ) { if ( $refresh ) { $this->cache->invalidate(); } $cached = $this->cache->get(); if ( $cached !== null ) { $this->lastBuildInfo = array( 'cache_enabled' => true, 'cache_hit' => true, 'generated_at' => $cached['generated_at'] ); return $cached['graph']; } } $graph = new Graph(); $edges = array(); foreach ( $this->registry->all() as $detector ) { $result = $detector->detect(); if ( ! isset( $result['nodes'], $result['edges'] ) || ! is_array( $result['nodes'] ) || ! is_array( $result['edges'] ) ) { throw new \UnexpectedValueException( 'Detectors must return nodes and edges arrays.' ); } foreach ( $result['nodes'] as $node ) { if ( ! $node instanceof Node ) { throw new \UnexpectedValueException( 'Detector nodes must be Node objects.' ); } $graph->addNode( $node ); } foreach ( $result['edges'] as $edge ) { if ( ! $edge instanceof Edge ) { throw new \UnexpectedValueException( 'Detector edges must be Edge objects.' ); } $edges[] = $edge; } } foreach ( $edges as $edge ) { $graph->addEdge( $edge ); } if ( $this->resolver !== null ) { foreach ( $this->resolver->resolve( $graph ) as $edge ) { $graph->addEdge( $edge ); } } $graph = $this->health !== null ? $this->health->evaluate( $graph ) : $graph; $generated_at = $this->cache !== null ? $this->cache->set( $graph ) : time(); $this->lastBuildInfo = array( 'cache_enabled' => $this->cache !== null, 'cache_hit' => false, 'generated_at' => $generated_at ); return $graph; } public function getLastBuildInfo(): array { return $this->lastBuildInfo; } }