<?php

/**
 * JCOGS Image Pro - Filter 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;

use Imagine\Image\ImageInterface;

/**
 * Filter Provider Interface
 * 
 * Allows external add-ons to register custom image filters that integrate
 * seamlessly with the core transformation pipeline.
 * 
 * Use Cases:
 * - Artistic filters (oil painting, watercolor, sketch, cartoon effects)
 * - Technical filters (advanced noise reduction, sharpening algorithms)
 * - Specialized effects (ASCII art, pixelation, glitch effects, vintage looks)
 * - Industry-specific processing (medical imaging, satellite imagery, forensics)
 * 
 * Priority Levels:
 * - 10: Core built-in filters (baseline implementations)
 * - 20-50: Local companion add-on filters (premium algorithms)
 * - 100+: Cloud API filters (highest quality, external services)
 * 
 * Integration Point:
 * ProcessImageStage::apply_filters() checks FilterProvider registry BEFORE
 * applying built-in filters. If provider found and available, provider's
 * apply() method is called. Otherwise falls back to built-in implementation.
 * 
 * Filter Naming:
 * - Use descriptive, lowercase names with underscores
 * - Examples: 'oil_painting', 'ascii_art', 'vintage_film'
 * - Avoid conflicts with core filter names
 * 
 * Extension add-ons can implement this interface and register their
 * providers via the 'jcogs_img_pro_register_providers' extension hook.
 * 
 * Example Implementation:
 * 
 * ```php
 * use Imagine\Image\ImageInterface;
 * 
 * class OilPaintingFilterProvider implements FilterProviderInterface
 * {
 *     public function getName(): string { return 'artistic_filters'; }
 *     public function getFilterName(): string { return 'oil_painting'; }
 *     public function getPriority(): int { return 30; }
 *     public function isAvailable(): bool { return extension_loaded('imagick'); }
 *     
 *     public function apply(ImageInterface $image, string $parameters, array $context): ImageInterface
 *     {
 *         // Parse parameters (supports named syntax via NamedParameterParser)
 *         $parser = new NamedParameterParser();
 *         $params = $parser->parse($parameters, [
 *             0 => 'radius',
 *             1 => 'sigma',
 *         ], ['radius' => 5, 'sigma' => 3]);
 *         
 *         // Apply oil painting effect using Imagine's native effects
 *         $image->effects()->oilPaint($params['radius'], $params['sigma']);
 *         
 *         return $image;
 *     }
 *     
 *     public function getOptions(): array
 *     {
 *         return [
 *             'description' => 'Oil painting artistic effect',
 *             'parameters' => [
 *                 'radius' => [
 *                     'type' => 'integer',
 *                     'description' => 'Brush radius (1-20)',
 *                     'default' => 5,
 *                     'min' => 1,
 *                     'max' => 20,
 *                 ],
 *                 'sigma' => [
 *                     'type' => 'integer',
 *                     'description' => 'Brush smoothness (1-10)',
 *                     'default' => 3,
 *                     'min' => 1,
 *                     'max' => 10,
 *                 ],
 *             ],
 *             'examples' => [
 *                 'Basic usage' => 'filter="oil_painting"',
 *                 'Custom settings (positional)' => 'filter="oil_painting|7|4"',
 *                 'Custom settings (named)' => 'filter="oil_painting|radius:7|sigma:4"',
 *             ],
 *         ];
 *     }
 * }
 * ```
 * 
 * Template Usage:
 * ```
 * {!-- Basic usage --}
 * {exp:jcogs_img_pro:img src="photo.jpg" filter="oil_painting"}
 * 
 * {!-- With parameters (positional syntax) --}
 * {exp:jcogs_img_pro:img src="photo.jpg" filter="oil_painting|7|4"}
 * 
 * {!-- With parameters (named syntax) --}
 * {exp:jcogs_img_pro:img src="photo.jpg" filter="oil_painting|radius:7|sigma:4"}
 * ```
 */
interface FilterProviderInterface
{
    /**
     * Get provider name for logging/debugging
     * 
     * Used in debug output and error messages. Can represent a collection
     * of related filters (e.g., 'artistic_filters' providing multiple effects).
     * 
     * @return string Provider identifier (e.g., 'artistic_filters', 'pro_sharpen', 'vintage_effects')
     */
    public function getName(): string;
    
    /**
     * Get filter name for parameter matching
     * 
     * This is the name users specify in templates via the filter parameter:
     * {exp:jcogs_img_pro:img filter="filter_name"}
     * 
     * Must be unique across all providers and core filters. Use descriptive,
     * lowercase names with underscores for multi-word filters.
     * 
     * @return string Filter name (e.g., 'oil_painting', 'ascii_art', 'vintage_film')
     */
    public function getFilterName(): string;
    
    /**
     * Get provider priority (higher = preferred if multiple filters share name)
     * 
     * If multiple providers register the same filter name, highest priority
     * wins. Core built-in filters use priority 10.
     * 
     * Priority Guidelines:
     * - 10: Core built-in filters
     * - 20-30: Enhanced local algorithms
     * - 40-50: Premium local filters
     * - 100+: Cloud API filters
     * 
     * @return int Priority value
     */
    public function getPriority(): int;
    
    /**
     * Check if provider is available
     * 
     * Should verify:
     * - Required PHP extensions present (imagick, gmagick, gd)
     * - Required libraries available
     * - API credentials configured (if applicable)
     * - System requirements met
     * 
     * Return false if filter cannot function. Do not throw exceptions.
     * 
     * @return bool True if filter can be used
     */
    public function isAvailable(): bool;
    
    /**
     * Apply filter to image
     * 
     * Receives Imagine ImageInterface and returns modified ImageInterface.
     * Must handle both positional and named parameter syntax.
     * 
     * Architecture Benefits:
     * - Works with any Imagine driver (GD, Imagick, Gmagick)
     * - No conversion overhead (direct ImageInterface manipulation)
     * - Can use Imagine's native effects or extract resources if needed
     * - Consistent with IMG Pro's internal pipeline architecture
     * 
     * Performance Considerations:
     * - This method called during image processing pipeline
     * - Keep execution time reasonable (< 100ms for local, < 2s for API)
     * - Prefer Imagine's native effects over manual pixel manipulation
     * - Log performance metrics for debugging
     * 
     * Error Handling:
     * - Throw exceptions for fatal errors (propagates to pipeline)
     * - Core will catch exceptions and use fallback if available
     * - Log warnings for non-fatal issues
     * 
     * Parameter Parsing:
     * - Support both positional and named syntax
     * - Use NamedParameterParser for complex parameters
     * - Provide sensible defaults for optional parameters
     * 
     * Implementation Options:
     * 
     * Option 1: Use Imagine Effects (Recommended)
     * ```php
     * public function apply(ImageInterface $image, string $parameters, array $context): ImageInterface
     * {
     *     $params = $this->parse_parameters($parameters);
     *     $image->effects()->blur($params['radius']);
     *     return $image;
     * }
     * ```
     * 
     * Option 2: Extract GD Resource (If Needed)
     * ```php
     * public function apply(ImageInterface $image, string $parameters, array $context): ImageInterface
     * {
     *     $imagine = $context['imagine'];
     *     
     *     // Convert to GD for custom pixel manipulation
     *     $temp = fopen('php://memory', 'r+');
     *     $image->save($temp, ['format' => 'png']);
     *     rewind($temp);
     *     $gd = imagecreatefromstring(stream_get_contents($temp));
     *     fclose($temp);
     *     
     *     // Your custom GD operations
     *     imagefilter($gd, IMG_FILTER_SEPIA);
     *     
     *     // Convert back to Imagine
     *     ob_start();
     *     imagepng($gd);
     *     $data = ob_get_clean();
     *     imagedestroy($gd);
     *     
     *     return $imagine->load($data);
     * }
     * ```
     * 
     * @param ImageInterface $image Imagine image to process (works with all drivers)
     * @param string $parameters Filter parameters from tag (unparsed string)
     *   Examples:
     *   - "5|3" (positional)
     *   - "radius:5|sigma:3" (named)
     *   - "" (empty - use defaults)
     * 
     * @param array $context Processing context with available services:
     *   [
     *     'imagine' => ImagineInterface,  // Imagine library instance (GD/Imagick/Gmagick)
     *     'utilities' => Utilities,       // Utilities service (debug_message, etc.)
     *     'tag_parameters' => array,      // All tag parameters from template
     *   ]
     * 
     * @return ImageInterface Modified Imagine image
     * 
     * @throws \Exception If filter fails fatally (caught by pipeline)
     */
    public function apply(ImageInterface $image, string $parameters, array $context): ImageInterface;
    
    /**
     * Get filter options for documentation/validation
     * 
     * Returns metadata about filter parameters, usage examples, and capabilities.
     * Used for:
     * - Auto-generating documentation
     * - Parameter validation in preset editor
     * - Help text in control panel
     * 
     * @return array Filter metadata:
     *   [
     *     'description' => string,           // Human-readable filter description
     *     'parameters' => array,             // Parameter definitions (see below)
     *     'examples' => array,               // Usage examples (see below)
     *     'performance' => string (optional), // Performance notes
     *     'requires' => array (optional),    // Required extensions/libraries
     *   ]
     * 
     * Parameter Definition Format:
     *   'param_name' => [
     *     'type' => 'integer'|'string'|'enum'|'float'|'boolean',
     *     'description' => string,           // Parameter description
     *     'default' => mixed,                // Default value
     *     'min' => int|float (optional),     // Minimum value (numeric types)
     *     'max' => int|float (optional),     // Maximum value (numeric types)
     *     'allowed_values' => array (optional), // Valid values (enum type)
     *     'required' => bool (optional),     // Is parameter required?
     *   ]
     * 
     * Example Format:
     *   'description' => 'template_code'   // Example description => template code
     */
    public function getOptions(): array;
}
