<?php
/**
 * Provider resolver Application-layer port.
 *
 * Narrow contract that maps a provider key (the §4 stable token —
 * `amazon`, `rakuten`, `yahoo_shopping`, ...) to a concrete
 * {@see \Affilun\Domain\Provider\ItemLookupProviderInterface}
 * implementation. The Phase 9 sync handler consumes this port so it
 * does not have to depend on the broader provider registry surface
 * the Phase 4+ slices populate; keeping the contract minimal lets the
 * sync layer stay testable with a one-line stub instead of having to
 * wire the full registry into a unit test.
 *
 * Design notes:
 *
 *   - The contract speaks only of single-item lookup. Search-side and
 *     affiliate-link-side resolution are not in scope here because
 *     the Phase 9 sync pipeline drives lookups exclusively. A future
 *     slice can add sibling resolvers for those surfaces without
 *     touching this port.
 *
 *   - "Provider not registered" and "provider registered but does
 *     not implement {@see ItemLookupProviderInterface}" are NOT
 *     distinct in the contract: both surface as
 *     {@see \Affilun\Application\Sync\Exception\UnknownProviderException}.
 *     The sync handler treats both as a `failed_terminal` outcome
 *     with the same `unknown_provider` code, so distinguishing them
 *     at this boundary would only multiply call-site branches
 *     without changing observable behaviour.
 *
 *   - Implementations MUST raise the exception rather than returning
 *     null. Returning a sentinel would conflict with the §10.1
 *     "失敗時に空配列を返してごまかす" prohibition lifted to the
 *     Application layer.
 *
 * @package Affilun\Application\Sync
 */

declare(strict_types=1);

namespace Affilun\Application\Sync;

use Affilun\Application\Sync\Exception\UnknownProviderException;
use Affilun\Domain\Provider\ItemLookupProviderInterface;

/**
 * Application-layer port that resolves a provider key to an
 * item-lookup-capable provider implementation.
 *
 * See the file-level docblock for the contract scope and the
 * "raise rather than return null" rule that binds implementations.
 */
interface ProviderResolver {

	/**
	 * Resolve the supplied provider key to its item-lookup-capable
	 * provider implementation.
	 *
	 * @param string $providerKey §4 stable provider key.
	 *
	 * @return ItemLookupProviderInterface Provider that can satisfy
	 *                                     the §6.3 single-item
	 *                                     lookup contract for this
	 *                                     key.
	 *
	 * @throws UnknownProviderException When no provider is registered
	 *                                  under `$providerKey`, or when
	 *                                  the matched provider does not
	 *                                  implement
	 *                                  {@see ItemLookupProviderInterface}.
	 */
	public function resolveItemLookup( string $providerKey ): ItemLookupProviderInterface;
}
