#!/usr/bin/env python3
"""
REGEX_REPLACE Executor
Company: eXonware.com
Author: eXonware Backend Team
Email: connect@exonware.com
Version: 0.0.1.8
"""

import re
from typing import Any, Optional
from ..base import AUniversalOperationExecutor
from ....contracts import QueryAction, ExecutionContext, ExecutionResult
from ....defs import OperationType
from ..utils import extract_items, extract_field_value


class RegexReplaceExecutor(AUniversalOperationExecutor):
    """
    REGEX_REPLACE operation executor - Replace regex matches within a field value.

    Compiled patterns are cached on the class to avoid recompilation overhead.

    params:
        field: source field name
        pattern: regular expression pattern
        replacement: replacement string (supports back-references like \\1)
        count: max replacements (default 0 = replace all)
        as_field: output field name (optional, defaults to overwriting field)
    """
    OPERATION_NAME = "REGEX_REPLACE"
    OPERATION_TYPE = OperationType.ADVANCED
    SUPPORTED_NODE_TYPES = []

    _pattern_cache: dict[str, re.Pattern] = {}

    def _do_execute(self, action: QueryAction, context: ExecutionContext) -> ExecutionResult:
        params = action.params
        node = context.node
        result_data = self._execute_op(node, params)
        return ExecutionResult(
            success=True,
            data=result_data,
            action_type=self.OPERATION_NAME,
            metadata={'operation': self.OPERATION_NAME}
        )

    def _compile(self, pattern: str) -> re.Pattern:
        compiled = self._pattern_cache.get(pattern)
        if compiled is None:
            compiled = re.compile(pattern)
            self._pattern_cache[pattern] = compiled
        return compiled

    def _execute_op(self, node: Any, params: dict) -> dict:
        items = extract_items(node)
        field = params.get('field', '')
        pattern = params.get('pattern', '')
        replacement = params.get('replacement', '')
        count = params.get('count', 0)
        as_field = params.get('as_field', field)
        regex = self._compile(pattern)

        result_items = []
        for item in items:
            item_copy = item.copy() if isinstance(item, dict) else {'value': item}
            val = extract_field_value(item, field)
            if val is not None:
                item_copy[as_field] = regex.sub(replacement, str(val), count=count)
            else:
                item_copy[as_field] = None
            result_items.append(item_copy)

        return {'items': result_items, 'count': len(result_items), 'field': field}


__all__ = ['RegexReplaceExecutor']
