o
    c:                     @   s\  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lm	Z	 dd
lm
Z
 ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ e
rdddlmZ ddlmZ edddZedddZedddZG dd deeef ZG dd deejejf ZG dd deejejf ZG dd deejej f Z!d S )!z  Dual ParserNode implementation     )Any)Generic)Iterable)List)Optional)Set)Tuple)Type)TYPE_CHECKING)TypeVar)apacheparser)
assertions)augeasparser)
interfaces)ApacheParserNode)AugeasParserNodeGenericAugeasParserNoder   )boundGenericApacheParserNoder   GenericDualNodeDualNodeBasec                   @   s   e Zd ZdZdededdfddZdeddfd	d
Zdede	fddZ
deded  fddZdee dedede	dee f
ddZdS )r   z Dual parser interface for in development testing. This is used as the
    base class for dual parser interface classes. This class handles runtime
    attribute value assertions.primary	secondaryreturnNc                 C   s   || _ || _d S )Nr   r   )selfr   r    r   P/opt/certbot/lib/python3.10/site-packages/certbot_apache/_internal/dualparser.py__init__    s   
zDualNodeBase.__init__msgc                 C   s   | j | | j| dS )z Call save for both parsers N)r   saver   )r   r   r   r   r   r    %   s   zDualNodeBase.saveanamec                 C   s@   t | j|}t | j|}|dkt|g}t|st|| |S )z Attribute value assertion metadata)getattrr   r   callableanyr   assertEqualSimple)r   r!   firstval	secondval
exclusionsr   r   r   __getattr__*   s   zDualNodeBase.__getattr__namec                 C      |  td|S )zA Traverses the ancestor tree and returns ancestors matching name find_ancestors_find_helperDualBlockNode)r   r+   r   r   r   r-   8   s   zDualNodeBase.find_ancestors	nodeclassfindfuncsearchkwargsc                 K   s  t | j||fi |}t | j||fi |}t|}t|}g }	|r7|r7|	||d |d d |	S |rK|D ]}
|	||d |
d q;|	S |r_|D ]}
|	||
|d d qO|	S t|t|ksiJ | ||}|D ]\}}|	|||d qq|	S )a.  A helper for find_* functions. The function specific attributes should
        be passed as keyword arguments.

        :param interfaces.ParserNode nodeclass: The node class for results.
        :param str findfunc: Name of the find function to call
        :param str search: The search term
        r   r   )r#   r   r   r   isPassNodeListappendlen_create_matching_list)r   r1   r2   r3   r4   primary_ressecondary_respass_primarypass_secondary	new_nodescmatchespsr   r   r   r/   <   s6   




zDualNodeBase._find_helper)__name__
__module____qualname____doc__r   r   r   strr    r   r*   r   r-   r	   r   r/   r   r   r   r   r      s    
c                       s*   e Zd ZdZdeddf fddZ  ZS )DualCommentNodez5 Dual parser implementation of CommentNode interface r4   r   Nc                       | dd | dd |d}|d}|s|r(|r|s J t || nt tjdi |tjdi | t	| j
| j dS )a<   This initialization implementation allows ordinary initialization
        of CommentNode objects as well as creating a DualCommentNode object
        using precreated or fetched CommentNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.CommentNode:

        :param CommentNode primary: Primary pre-created CommentNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param CommentNode secondary: Secondary pre-created CommentNode
        r   Nr   r   )
setdefaultpopsuperr   r   AugeasCommentNoder   ApacheCommentNoder   assertEqualr   r   r   r4   r   r   	__class__r   r   r   i      

zDualCommentNode.__init__)rB   rC   rD   rE   r   r   __classcell__r   r   rP   r   rG   e   s    rG   c                       sJ   e Zd ZU dZeed< deddf fddZdee ddfdd	Z	  Z
S )
DualDirectiveNodez7 Dual parser implementation of DirectiveNode interface 
parametersr4   r   Nc                    rH   )aL   This initialization implementation allows ordinary initialization
        of DirectiveNode objects as well as creating a DualDirectiveNode object
        using precreated or fetched DirectiveNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.DirectiveNode:

        :param DirectiveNode primary: Primary pre-created DirectiveNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param DirectiveNode secondary: Secondary pre-created DirectiveNode
        r   Nr   r   )rI   rJ   rK   r   r   AugeasDirectiveNoder   ApacheDirectiveNoder   rN   r   r   rO   rP   r   r   r      rR   zDualDirectiveNode.__init__c                 C   s,   | j | | j| t| j | j dS )zf Sets parameters and asserts that both implementation successfully
        set the parameter sequence N)r   set_parametersr   r   rN   )r   rU   r   r   r   rX      s   z DualDirectiveNode.set_parameters)rB   rC   rD   rE   rF   __annotations__r   r   r   rX   rS   r   r   rP   r   rT      s
   
 rT   c                	       sP  e Zd ZdZdeddf fddZ		d%dedeee  d	ee	 dd fd
dZ
		d%dedeee  d	ee	 defddZ		d&ded	ee	 defddZdeej deej deeejejf  fddZd'dededed  fddZd'dededee fddZdedee fddZd(dd Zdee fd!d"Zdee fd#d$Z  ZS ))r0   z3 Dual parser implementation of BlockNode interface r4   r   Nc                    rH   )a,   This initialization implementation allows ordinary initialization
        of BlockNode objects as well as creating a DualBlockNode object
        using precreated or fetched BlockNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.BlockNode:

        :param BlockNode primary: Primary pre-created BlockNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param BlockNode secondary: Secondary pre-created BlockNode
        r   Nr   r   )rI   rJ   rK   r   r   AugeasBlockNoder   ApacheBlockNoder   rN   r   r   rO   rP   r   r   r      rR   zDualBlockNode.__init__r+   rU   positionc                 C   8   | j |||}| j|||}t|| t||dS )z Creates a new child BlockNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualBlockNode object
        encapsulating both of the newly created objects r   )r   add_child_blockr   r   rN   r0   r   r+   rU   r\   primary_newsecondary_newr   r   r   r^         zDualBlockNode.add_child_blockc                 C   r]   )z Creates a new child DirectiveNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualDirectiveNode
        object encapsulating both of the newly created objects r   )r   add_child_directiver   r   rN   rT   r_   r   r   r   rc      rb   z!DualBlockNode.add_child_directive commentc                 C   s8   | j j||d}| jj||d}t|| t||dS )z Creates a new child CommentNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualCommentNode
        object encapsulating both of the newly created objects )re   r\   )r+   r\   r   )r   add_child_commentr   r   rN   rG   )r   re   r\   r`   ra   r   r   r   rf      rb   zDualBlockNode.add_child_commentprimary_listsecondary_listc              
   C   sb   g }|D ]*}d}|D ]}zt || |}W  n	 ty    Y q
w |r+|||f qtd|S )a   Matches the list of primary_list to a list of secondary_list and
        returns a list of tuples. This is used to create results for find_
        methods.

        This helper function exists, because we cannot ensure that the list of
        search results returned by primary.find_* and secondary.find_* are ordered
        in a same way. The function pairs the same search results from both
        implementations to a list of tuples.
        NzCould not find a matching node.)r   rN   AssertionErrorr6   )r   rg   rh   matchedr@   matchrA   r   r   r   r8      s   z#DualBlockNode._create_matching_listTexcludec                 C      | j td||dS )a  
        Performs a search for BlockNodes using both implementations and does simple
        checks for results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualBlockNode
        instances that encapsulate the pairs of returned BlockNode objects.
        find_blocksrl   r.   r   r+   rl   r   r   r   rn        
	zDualBlockNode.find_blocksc                 C   rm   )a  
        Performs a search for DirectiveNodes using both implementations and
        checks the results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualDirectiveNode
        instances that encapsulate the pairs of returned DirectiveNode objects.
        find_directivesro   )r/   rT   rp   r   r   r   rr     rq   zDualBlockNode.find_directivesc                 C   r,   )a  
        Performs a search for CommentNodes using both implementations and
        checks the results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualCommentNode
        instances that encapsulate the pairs of returned CommentNode objects.
        find_comments)r/   rG   )r   re   r   r   r   rs   $  s   	zDualBlockNode.find_commentschildc                 C   s    | j |j  | j|j dS )zDeletes a child from the ParserNode implementations. The actual
        ParserNode implementations are used here directly in order to be able
        to match a child to the list of children.N)r   delete_childr   )r   rt   r   r   r   ru   /  s   zDualBlockNode.delete_childc                 C   $   | j  }| j }t|| |S )zQ Fetches the list of unsaved file paths and asserts that the lists
        match )r   unsaved_filesr   r   r&   )r   primary_filessecondary_filesr   r   r   rw   7  s   

zDualBlockNode.unsaved_filesc                 C   rv   )an  
        Returns a list of file paths that have currently been parsed into the parser
        tree. The returned list may include paths with wildcard characters, for
        example: ['/etc/apache2/conf.d/*.load']

        This is typically called on the root node of the ParserNode tree.

        :returns: list of file paths of files that have been parsed
        )r   parsed_pathsr   r   assertEqualPathsList)r   primary_pathssecondary_pathsr   r   r   rz   @  s   

zDualBlockNode.parsed_paths)NN)rd   N)T)rt   r0   r   N)rB   rC   rD   rE   r   r   rF   r   r   intr^   rT   rc   rG   rf   r   r   
ParserNoder   r8   boolrn   rr   rs   ru   r   rw   rz   rS   r   r   rP   r   r0      sF    




	r0   N)"rE   typingr   r   r   r   r   r   r   r	   r
   r   certbot_apache._internalr   r   r   r   %certbot_apache._internal.apacheparserr   %certbot_apache._internal.augeasparserr   r   r   r   r   rL   rM   rG   rV   rW   rT   rZ   r[   r0   r   r   r   r   <module>   s>    J *