<?php

/**
 * JCOGS Image Pro - Variable Provider Interface
 * Extension Architecture Foundation
 * 
 * @category   ExpressionEngine Add-on
 * @package    JCOGS Image Pro
 * @author     JCOGS Design <contact@jcogs.net>
 * @copyright  Copyright (c) 2021 - 2025 JCOGS Design
 * @license    https://jcogs.net/add-ons/license/jcogs_img_pro
 * @version    2.0.6
 * @link       https://JCOGS.net/
 * @since      Extension Architecture v2.0
 */

namespace JCOGSDesign\JCOGSImagePro\Service\Provider;

/**
 * Variable Provider Interface
 * 
 * Allows external add-ons to inject additional output variables into
 * template tags without modifying core OutputGenerationService.
 * 
 * Use Cases:
 * - EXIF data extension (camera model, GPS coordinates, capture settings)
 * - Custom metadata fields from companion add-ons
 * - Computed values (dominant colors, image complexity scores, focal points)
 * - External API data (reverse geocoding, AI image recognition labels)
 * 
 * Priority Levels:
 * - 10-50: Computed/local data (fast, no external dependencies)
 * - 100+: API-based data (slower, requires caching)
 * 
 * Integration Point:
 * OutputGenerationService::generate_output_variables() calls all registered
 * VariableProviders after core variables are generated. Additional variables
 * are merged into the output array.
 * 
 * Variable Naming:
 * - Use getVariablePrefix() to avoid conflicts with core variables
 * - Example: prefix 'exif' makes 'camera' become 'exif_camera'
 * - Core variables always take precedence in conflicts
 * 
 * Extension add-ons can implement this interface and register their
 * providers via the 'jcogs_img_pro_register_providers' extension hook.
 * 
 * Example Implementation:
 * 
 * ```php
 * class ExifVariableProvider implements VariableProviderInterface
 * {
 *     public function getName(): string { return 'exif_extended'; }
 *     public function getPriority(): int { return 20; }
 *     public function isAvailable(): bool { return function_exists('exif_read_data'); }
 *     public function getVariablePrefix(): ?string { return 'exif'; }
 *     
 *     public function getAdditionalVariables(array $context): array
 *     {
 *         $source_path = $context['source_path'];
 *         $exif = @exif_read_data($source_path);
 *         
 *         return [
 *             'camera' => $exif['Model'] ?? 'Unknown',
 *             'lens' => $exif['LensModel'] ?? 'Unknown',
 *             'iso' => $exif['ISOSpeedRatings'] ?? null,
 *             // ... additional variables
 *         ];
 *     }
 * }
 * ```
 * 
 * Template Usage:
 * ```
 * {exp:jcogs_img_pro:img src="photo.jpg"}
 *     Camera: {exif_camera}
 *     Lens: {exif_lens}
 *     ISO: {exif_iso}
 * {/exp:jcogs_img_pro:img}
 * ```
 */
interface VariableProviderInterface
{
    /**
     * Get provider name for logging/debugging
     * 
     * Used in debug output and error messages. Should be unique and descriptive.
     * 
     * @return string Provider identifier (e.g., 'exif_extended', 'ai_labels', 'color_analysis')
     */
    public function getName(): string;
    
    /**
     * Get provider priority (higher = preferred for conflict resolution)
     * 
     * If multiple providers return the same variable name, the highest
     * priority provider wins. Core variables always take precedence.
     * 
     * Priority Guidelines:
     * - 10-20: Basic metadata extraction (EXIF, IPTC)
     * - 30-50: Computed analysis (colors, complexity, features)
     * - 100+: API-based enrichment (AI labels, geocoding)
     * 
     * @return int Priority value
     */
    public function getPriority(): int;
    
    /**
     * Check if provider is available and configured
     * 
     * Should verify:
     * - Required PHP extensions present (e.g., exif, imagick)
     * - API credentials configured (if applicable)
     * - Network connectivity available (for API providers)
     * 
     * Return false if provider cannot function. Do not throw exceptions.
     * 
     * @return bool True if provider can be used
     */
    public function isAvailable(): bool;
    
    /**
     * Get additional output variables
     * 
     * Called after core variables are generated. Returns associative array of
     * variable names and values to merge into template output.
     * 
     * Performance Considerations:
     * - This method called for EVERY image tag
     * - Cache expensive operations (API calls, complex analysis)
     * - Keep execution time < 10ms for local operations
     * - Use isAvailable() to fail fast if prerequisites missing
     * 
     * Error Handling:
     * - Catch all exceptions internally
     * - Return empty array on error (graceful degradation)
     * - Log errors for debugging but don't propagate
     * 
     * @param array $context Processing context with available data:
     *   [
     *     'source_path' => string,           // Original image absolute path
     *     'output_path' => string,           // Generated cache file path
     *     'image_resource' => resource|null, // GD image resource (if available)
     *     'parameters' => array,             // All tag parameters from template
     *     'core_variables' => array,         // Core variables already generated
     *   ]
     * 
     * @return array Additional variables to merge into output:
     *   [
     *     'variable_name' => mixed,  // Variable value (string, int, float, bool)
     *     'camera' => 'Canon EOS 5D',
     *     'gps_lat' => 37.7749,
     *     'gps_lng' => -122.4194,
     *     'dominant_color' => '#3A7BD5',
     *     'ai_labels' => 'landscape, mountains, sunset',
     *     // ... etc.
     *   ]
     * 
     * Note: Variable names will be prefixed automatically if getVariablePrefix()
     * returns a value. Do not include prefix in returned array keys.
     */
    public function getAdditionalVariables(array $context): array;
    
    /**
     * Get variable prefix (optional)
     * 
     * If provided, all variables from this provider will be prefixed with
     * this string to avoid conflicts with core variables or other providers.
     * 
     * Example: prefix 'exif' means variable 'camera' becomes 'exif_camera'
     * 
     * Prefix Guidelines:
     * - Use short, descriptive prefixes (3-6 characters)
     * - Use lowercase letters only
     * - Avoid underscores (added automatically)
     * - Return null for no prefix (variables used as-is)
     * 
     * @return string|null Variable prefix (e.g., 'exif', 'ai', 'color') or null for no prefix
     */
    public function getVariablePrefix(): ?string;
}
