<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Resolvers;

use Ekesto\CacheInvalidator\Core\Relationships\RelationshipCycleDetector;
use Ekesto\CacheInvalidator\Core\Relationships\RelationshipGraph;
use Ekesto\CacheInvalidator\Core\Relationships\RelationshipProviderRegistry;
use Ekesto\CacheInvalidator\Support\Debug;

/**
 * Lite-safe facade over the relationship graph + propagation seam.
 *
 * Public static signatures are preserved for existing call sites. Configured /
 * watched post-type reads and cycle validation are Lite-safe and resolved here.
 * Propagation (resolveAffectedHosts / resolveRelationshipEdges) is delegated to
 * the registered relationship provider, which is a Lite-safe no-op unless the
 * premium relationship implementation is present. The Pro-only
 * `ekesto_ci_relationship_meta_keys` filter is never applied in this file.
 */
class RelationshipGraphResolver
{
    /**
     * All configured post types (keys under settings post_types).
     *
     * @return string[]
     */
    public static function getConfiguredPostTypes(): array
    {
        return RelationshipGraph::getConfiguredPostTypes();
    }

    /**
     * Configured post types + all relationship slugs referenced in settings.
     *
     * @return string[]
     */
    public static function getWatchedPostTypes(): array
    {
        return RelationshipGraph::getWatchedPostTypes();
    }

    /**
     * Resolve configured host post types affected by a trigger post type.
     *
     * @param string $triggerPostType
     * @return string[]
     */
    public static function resolveAffectedHosts(string $triggerPostType): array
    {
        try {
            return RelationshipProviderRegistry::current()->resolveAffectedHosts($triggerPostType);
        } catch (\Throwable $throwable) {
            Debug::log('relationship_provider_error', [
                'method' => 'resolveAffectedHosts',
                'error' => $throwable->getMessage(),
            ]);
            return [];
        }
    }

    /**
     * Resolve ordered propagation edges [from_pt, to_pt] in BFS order.
     *
     * @param string $triggerPostType
     * @return array<int,array{0:string,1:string}>
     */
    public static function resolveRelationshipEdges(string $triggerPostType): array
    {
        try {
            return RelationshipProviderRegistry::current()->resolveRelationshipEdges($triggerPostType);
        } catch (\Throwable $throwable) {
            Debug::log('relationship_provider_error', [
                'method' => 'resolveRelationshipEdges',
                'error' => $throwable->getMessage(),
            ]);
            return [];
        }
    }

    /**
     * Detect cycles in host -> relationships adjacency.
     *
     * @param array<string,string[]> $adjacencyList
     * @return array{has_cycle:bool,cycle_path:string[]}
     */
    public static function detectCycle(array $adjacencyList): array
    {
        return RelationshipCycleDetector::detect($adjacencyList);
    }
}
