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

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 CopyExecutor(AUniversalOperationExecutor):
    """COPY - Copy records between logical collections."""
    OPERATION_NAME = "COPY"
    OPERATION_TYPE = OperationType.DATA_OPS
    SUPPORTED_NODE_TYPES = []

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

    def _matches_filter(self, item: Any, filter_spec: Optional[dict]) -> bool:
        if not filter_spec:
            return True
        if not isinstance(filter_spec, dict):
            return False
        return all(extract_field_value(item, key) == value for key, value in filter_spec.items())

    def _execute_copy(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        source = params.get("source", node)
        target = params.get("target")
        filter_spec = params.get("filter")

        source_items = extract_items(source)
        copied_items = [item for item in source_items if self._matches_filter(item, filter_spec)]

        return {
            "items": copied_items,
            "count": len(copied_items),
            "copied_count": len(copied_items),
            "source_count": len(source_items),
            "target": target,
            "filter": filter_spec,
        }
