o
    6åi§)  ã                   @   s¸   U d Z ddlmZmZmZmZ ddlmZ eG dd„ dƒƒZG dd„ dƒZ	G dd	„ d	ƒZ
d
aee
 ed< de
fdd„ZddedededeeeeB f fdd„Zdededefdd„Zd
S )zÀ
Plugin Parameter Validation System

Provides comprehensive validation for plugin parameters based on their schema.
Supports type validation, required checks, default values, and constraints.
é    )ÚAnyÚOptionalÚDictÚList)Ú	dataclassc                   @   s*   e Zd ZU dZeed< eed< eed< dS )ÚValidationErrorz3Represents a validation error for a specific field.ÚfieldÚmessageÚtypeN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__© r   r   ú9/home/byschii/byschiidev/penelope/lib/plugin_validator.pyr      s
   
 r   c                   @   sn   e Zd ZdZdd„ Zddededefdd	„Zd
efdd„Zd
efdd„Z	d
e
eee
eef  f fdd„ZdS )ÚValidationResultzResult of parameter validation.c                 C   s
   g | _ d S )N)Úerrors©Úselfr   r   r   Ú__init__   s   
zValidationResult.__init__Ú
validationr   r	   Ú
error_typec                 C   s   | j  t|||ƒ¡ dS )zAdd a validation error.N)r   Úappendr   )r   r   r	   r   r   r   r   Ú	add_error   s   zValidationResult.add_errorÚreturnc                 C   s   t | jƒdkS )zCheck if validation passed.r   )Úlenr   r   r   r   r   Úis_valid   s   zValidationResult.is_validc                 C   s   | j sdS | j d jS )z)Get a single error message (first error).Ú r   )r   r	   r   r   r   r   Úget_error_message#   s   z"ValidationResult.get_error_messagec                 C   sB   i }| j D ]}|j|vrg ||j< ||j  |j|jdœ¡ q|S )z%Get detailed errors grouped by field.)r	   r
   )r   r   r   r	   r
   )r   Úerrors_by_fieldÚerrorr   r   r   Úget_detailed_errors)   s   




þz$ValidationResult.get_detailed_errorsN)r   )r   r   r   r   r   r   r   Úboolr   r    r   r   r#   r   r   r   r   r      s    &r   c                   @   sˆ   e Zd ZdZdededefdd„Zdededefdd„Zdeded	efd
d„Z	ded	efdd„Z
ded	efdd„Zded	efdd„ZdS )ÚPluginValidatorzå
    Validates plugin parameters against their schema.
    
    Performs:
    - Required parameter checking
    - Type validation
    - Constraint validation (min/max for numbers, pattern for strings)
    - Custom validation
    ÚpluginÚparamsr   c                 C   s:   |  ¡ }|jjD ]}|j|vr|jdur|j||j< q|S )zÿ
        Apply default values from plugin parameter schema.
        
        Args:
            plugin: Plugin instance with metadata
            params: Request parameters
            
        Returns:
            Parameters with defaults applied
        N)ÚcopyÚmetadataÚ
parametersÚnameÚdefault©r   r&   r'   ÚresultÚ	param_defr   r   r   Úapply_defaultsD   s   €zPluginValidator.apply_defaultsc                 C   s4   t ƒ }|  |||¡ |jjD ]	}|  |||¡ q|S )a	  
        Validate parameters against plugin schema.
        
        Args:
            plugin: Plugin instance with metadata
            params: Request parameters to validate
            
        Returns:
            ValidationResult with any errors found
        )r   Ú_run_custom_validationr)   r*   Ú_validate_parameterr-   r   r   r   ÚvalidateX   s
   zPluginValidator.validater.   c              
   C   sv   t |dƒr9z| |¡}|r| d|d¡ W dS W dS  ty8 } z| ddt|ƒ› d¡ W Y d}~dS d}~ww dS )z+Run plugin's custom validation if provided.Úvalidate_paramsÚ_customÚcustomzValidation error: N)Úhasattrr4   r   Ú	Exceptionr   )r   r&   r'   r.   Úcustom_errorÚer   r   r   r1   n   s   

ÿ&€ÿûz&PluginValidator._run_custom_validationc                 C   sb   |j }|jr||vr| |d|› dd¡ dS ||vrdS || }|  |||¡ |  |||¡ dS )zValidate a single parameter.zMissing required parameter: 'ú'ÚrequiredN)r+   r<   r   Ú_validate_typeÚ_validate_constraints)r   r/   r'   r.   Ú
param_nameÚvaluer   r   r   r2   x   s   
ýz#PluginValidator._validate_parameterr@   c                 C   s,  |j }|j}|dkr t|ttfƒs| |d|› dd¡ dS dS |dkr8t|tƒs6| |d|› dd¡ dS dS |dv rot|tƒsN| |d|› dd¡ dS |d	kri| d
¡sk| d¡sm| |d|› dd¡ dS dS dS dS |dkr|j	r’||j	vr”d 
|j	¡}| |d|› d|› d¡ dS dS dS dS )zValidate parameter type.ÚnumberúParameter 'z' must be a numberr
   Úcheckboxz' must be a boolean©ÚtextÚtextareaÚurlz' must be a stringrG   zhttp://zhttps://z+' must be a valid URL (http:// or https://)Úselectz, z' must be one of: N)r
   r+   Ú
isinstanceÚintÚfloatr   r$   r   Ú
startswithÚoptionsÚjoin)r   r/   r@   r.   Ú
param_typer?   Úoptions_strr   r   r   r=   ‘   sX   
ýÿ

ýÿ

ý
ýýýýzPluginValidator._validate_typec                 C   s  |j }|j}|dkrKt|ttfƒrKt|dƒr.|jdur.||jk r.| |d|› d|j› d¡ t|dƒrK|jdurK||jkrK| |d|› d|j› d¡ |d	v r¾t|t	ƒrÀt|d
ƒrt|j
durtt|ƒ|j
k rt| |d|› d|j
› dd¡ t|dƒr”|jdur”t|ƒ|jkr”| |d|› d|j› dd¡ t|dƒrÂ|jdurÄddl}| |j|¡sÆt|ddƒ}| |d|› d|› d¡ dS dS dS dS dS dS )ae  
        Validate parameter constraints (min/max for numbers, length for strings, etc.).
        
        Looks for additional attributes on param_def:
        - min: Minimum value for numbers or minimum length for strings
        - max: Maximum value for numbers or maximum length for strings
        - pattern: Regex pattern for string validation
        rA   ÚminNrB   z' must be at least Ú
constraintÚmaxz' must be at most rD   Ú
min_lengthz charactersÚ
max_lengthÚpatternr   Úpattern_descriptionzthe required formatz' must match )r+   r
   rI   rJ   rK   r7   rQ   r   rS   r   rT   r   rU   rV   ÚreÚmatchÚgetattr)r   r/   r@   r.   r?   rO   rX   Úpattern_descr   r   r   r>   Ã   sX   	
ý
ýýýýêz%PluginValidator._validate_constraintsN)r   r   r   r   r   Údictr0   r   r3   r1   r2   r=   r>   r   r   r   r   r%   9   s    

2r%   NÚ
_validatorr   c                   C   s   t du rtƒ a t S )z"Get the global validator instance.N)r]   r%   r   r   r   r   Úget_validator  s   r^   Fr&   r'   Údetailedc                 C   s:   t ƒ }| | |¡}| ¡ rdS |rd| ¡ fS d| ¡ fS )a  
    Validate plugin parameters.
    
    Args:
        plugin: Plugin instance with metadata
        params: Request parameters
        detailed: If True, return detailed error information
        
    Returns:
        Tuple of (is_valid, error_message_or_details)
    )Tr   F)r^   r3   r   r#   r    )r&   r'   r_   Ú	validatorr.   r   r   r   Úvalidate_plugin_params  s   ra   c                 C   s   t ƒ }| | |¡S )zÌ
    Apply default values to parameters.
    
    Args:
        plugin: Plugin instance with metadata
        params: Request parameters
        
    Returns:
        Parameters with defaults applied
    )r^   r0   )r&   r'   r`   r   r   r   Úapply_default_values#  s   rb   )F)r   Útypingr   r   r   r   Údataclassesr   r   r   r%   r]   r   r^   r\   r$   Útupler   ra   rb   r   r   r   r   Ú<module>   s   $ H(