
    ɧ-i(                         d Z ddlZddlZddlmZmZmZmZ ddlmZ  ej	        e
          ZdZdZdZ G d d	          Z G d
 d          ZdS )zX
Diff Service
Handles parsing and applying SEARCH/REPLACE diff blocks from AI responses
    N)ListDictTupleOptional)diff_match_patchz<<<<<<< SEARCHz=======z>>>>>>> REPLACEc                   "    e Zd ZdZdedefdZdS )	DiffBlockz-Represents a single SEARCH/REPLACE diff blockoriginalupdatedc                 "    || _         || _        d S N)r
   r   )selfr
   r   s      D/var/www/html/web-builder-api.evdpl.com/src/services/diff_service.py__init__zDiffBlock.__init__   s         N)__name__
__module____qualname____doc__strr    r   r   r	   r	      s<        77 s      r   r	   c            
           e Zd ZdZededee         fd            Zedededede	e         fd            Z
ed	ed
edeeeef         fd            ZdS )DiffServicez,Service for parsing and applying diff blockscontentreturnc                    g }|                      d          }d}|t          |          k     r<||                                         t          k    rg }g }|dz  }|t          |          k     ry||                                         t          k    rV|                    ||                    |dz  }|t          |          k     r#||                                         t          k    V|t          |          k    s#||                                         t          k    rt                              dt           dt          d          	                    |                      |t          |          k     r6t          ||         vr'|dz  }|t          |          k     rt          ||         v'|dz  }|t          |          k     ry||                                         t          k    rV|                    ||                    |dz  }|t          |          k     r#||                                         t          k    V|t          |          k    s#||                                         t          k    rt                              dt           dt          d          	                    |                      |t          |          k     r6t          ||         vr'|dz  }|t          |          k     rt          ||         v'd	                    |          }d	                    |          }|                    t          ||                     |dz  }|t          |          k     <|S )z
        Parse AI response content for SEARCH/REPLACE blocks.
        
        Args:
            content: The AI response content
            
        Returns:
            List of DiffBlock objects
        
r      z,Malformed diff block: Missing or misplaced 'z%' after SEARCH block. Block content: 
   z&' after REPLACE block. Block content: )splitlenstripSEARCH_STARTDIVIDERappendloggerwarningchrjoinREPLACE_ENDr	   )r   blockslinesioriginal_linesupdated_linesoriginal_textupdated_texts           r   parse_diff_blockszDiffService.parse_diff_blocks   s(    d###e**nnQx~~<//!# "Q #e**nnq)9)9W)D)D"))%(333FA #e**nnq)9)9W)D)D E

??eAhnn&6&6'&A&ANNIw I I*-b'',,~*F*FI I  
 c%jj..\q-I-IQ c%jj..\q-I-IQ #e**nnq)9)9[)H)H!((q222FA #e**nnq)9)9[)H)H E

??eAhnn&6&6+&E&ENNH{ H H*-b'',,}*E*EH H  
 c%jj..\q-I-IQ c%jj..\q-I-I !%		. 9 9#yy77i|DDEEEFA[ #e**nn^ r   current_htmloriginal_blockupdated_blockc                    t                      }|}|                    d          s|dz   | v r|dz   }|}|                    d          r|r|                    d          s|dz   }|                    d          r|sd}|| v rWt                              d           |                     |          }| d|         |z   | |t          |          z   d         z   S d                    |                                          }d                    |                                           }||v rt                              d           |                    d          }	t          |	          dk    r|	d                                         }
|
| v r| 	                    |
          }|}|	dd         D ]V}| 	                    |                                |          }|d	k    r%|t          |                                          z   }U n| d|         |z   | |d         z   S |
                    ||          }d
|_        d
|_        d|_        |                    ||           \  }}t          |          rt                              d           |S t                              d|            t                              dt%          |                      dS )a  
        Apply a single diff block to the current HTML content using diff-match-patch for fuzzy matching.
        
        Args:
            current_html: The current HTML content
            original_block: The content from the SEARCH block
            updated_block: The content from the REPLACE block
            
        Returns:
            The updated HTML content, or None if application failed
        r    z3Found exact match, using direct string replacement.N z8Found normalized match, using direct string replacement.r   r   g      ?i  z2Successfully applied patch using diff-match-patch.z:Patch application failed using diff-match-patch. Results: z.Search block not found in HTML. Search block:
)r   endswithr&   infoindexr!   r)   r    r"   find
patch_makeMatch_ThresholdPatch_DeleteThresholdMatch_Distancepatch_applyallr'   errorrepr)r3   r4   r5   dmpsearch_blockreplace_blockr<   normalized_searchnormalized_htmlsearch_lines
first_linestart_index	end_indexlinenext_line_startpatchespatched_htmlresultss                     r   apply_single_diffzDiffService.apply_single_diff]   s
       &&&t,, 	1.42GL1X1X)D0L &  && 	1= 	1AWAWX\A]A] 	1)D0M   && 	} 	M <''KKMNNN &&|44E'-7,usS_O`O`G`GaGa:bbb  HH\%7%7%9%9::((<#5#5#7#788//KKRSSS'--d33L<  1$$)!_2244
--"."3"3J"?"?K +I ,QRR 0 e e*6*;*;DJJLL)*T*T*b00(7#djjll:K:K(KII!E  ,L[L9MILYbYcYcLddd ..}== "$'!! # F Fg w<< 	KKLMMMNNaX_aabbbLL_4P\K]K]__```4r   original_htmlai_response_contentc           	         t                                         }|st                              d           t	          fdt
          t          t          fD                       rd}| d|fS                                 	                                }|
                    d          s|
                    d          rDt                              d           dd	lm}  |            }|                              }|d
dfS t                              d           | ddfS t                              dt          |           d           | }t!          |          D ]\  }	}
t                              d|	dz    dt          |           d           t                               ||
j        |
j                  }|t                              d|	dz    d           t                              d|
j         d|
j                    |
j        r |
j                            d          d         nd}|r|                    |          }|dk    rmt/          d|dz
            }t1          t          |          |t          |
j                  z   dz             }t                              d|||                     d|	dz    dt          |           d}|d|fc S |}t                              d            |d
dfS )!aJ  
        Apply all parsed diff blocks sequentially to the original HTML.
        
        Args:
            original_html: The initial HTML content
            ai_response_content: The full response from the AI containing diff blocks
            
        Returns:
            Tuple of (final_html, success, error_message)
        z8AI response did not contain valid SEARCH/REPLACE blocks.c              3       K   | ]}|v V  	d S r   r   ).0markerrV   s     r   	<genexpr>z*DiffService.apply_diffs.<locals>.<genexpr>   s)      ddV600ddddddr   zTAI response contained malformed or unparseable diff blocks. Could not apply changes.Fz<!doctype htmlz<htmlz[AI response seems to be full HTML despite diff instructions. Extracting HTML from response.r   )	AIServiceTr7   z]No valid diff blocks found and response doesn't look like full HTML. Returning original HTML.z"No changes detected in AI responsezFound z diff blocks to apply.zApplying block r   /z...NzFailed to apply diff block :z--- SEARCH ---
z
--- REPLACE ---
r   r9      i,  z--- CURRENT CONTEXT ---
z$Failed to apply AI-suggested change zA. The 'SEARCH' block might not accurately match the current code.z%All diff blocks applied successfully.)r   r2   r&   r'   anyr#   r$   r*   r"   lower
startswithservices.ai_servicer\   _extract_html_from_responser;   r!   	enumeraterT   r
   r   rD   r    r=   maxmin)rU   rV   diff_blocks	error_msgtrimmed_responser\   
ai_serviceextracted_htmlr3   r-   blockresultrL   context_indexcontext_startcontext_ends    `              r   apply_diffszDiffService.apply_diffs   sD    "334GHH 	NNNUVVV ddddgWb?cddddd 7r	$eY66  388::@@BB**+;<< 0@P@[@[\c@d@d 0|}}}999999&Y[[
!+!G!GH[!\!\%tR//NNz{{{ %)MMMES--EEEFFF$!+.. 	" 	"HAuKKG!a%GG#k2B2BGGGHHH 22<QVQ^__F~C1q5CCCDDDbbbSXS`bbccc ?DnTU^11$77::RT
 l$0$5$5j$A$AM$**(+A}s/B(C(C&)#l*;*;]SQVQ_M`M`=`cf=f&g&g%jm\gNgAh%j%jkkk _1q5  _  _3{K[K[  _  _  _	#UI5555!LL;<<<T2%%r   N)r   r   r   r   staticmethodr   r   r	   r2   r   rT   r   boolrr   r   r   r   r   r      s        66=3 =4	? = = = \=~ J JS JQT JYabeYf J J J \JX =&3 =&S =&U3PTVY>EZ =& =& =& \=& =& =&r   r   )r   reloggingtypingr   r   r   r   r   	getLoggerr   r&   r#   r$   r*   r	   r   r   r   r   <module>ry      s    
 
			  . . . . . . . . . . . . - - - - - -		8	$	$  
       N& N& N& N& N& N& N& N& N& N&r   