#!/usr/bin/env python3
"""
#exonware/xwquery/src/exonware/xwquery/executors/graph/simple_path_executor.py
SIMPLE_PATH Operation Executor - Find simple paths (no cycles)
Company: eXonware.com
Author: eXonware Backend Team
Email: connect@exonware.com
Version: 0.0.1.8
Generation Date: 15-Nov-2025
"""

from typing import Any
from ..base import AUniversalOperationExecutor
from ....contracts import QueryAction, ExecutionContext, ExecutionResult


class SimplePathExecutor(AUniversalOperationExecutor):
    """
    SIMPLE_PATH operation executor - Find simple paths (no repeated vertices).
    A simple path is a path where no vertex is visited more than once.
    This is the default behavior for most path operations.
    """
    OPERATION_NAME = "SIMPLE_PATH"

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

    def _execute_simple_path(self, node: Any, params: dict, context: ExecutionContext) -> dict:
        """
        Execute SIMPLE_PATH - Find simple path (no cycles).
        Root cause fixed: Missing SIMPLE_PATH operation.
        Solution: Full implementation with cycle-avoiding path finding.
        REUSE: Leverages path finding from path_executor with cycle detection.
        Priority Alignment:
        - Usability (#2): Standard simple path syntax.
        - Maintainability (#3): Reuses path finding logic.
        - Performance (#4): Efficient cycle-avoiding path finding.
        - Extensibility (#5): Supports various path constraints.
        """
        from collections import deque
        source = params.get('source', params.get('start'))
        target = params.get('target', params.get('end'))
        max_length = params.get('max_length', 10)
        if not source or not target:
            return {
                'path': [],
                'source': source,
                'target': target,
                'path_length': 0,
                'error': 'Both source and target required'
            }
        # Try to use xwnode graph capabilities
        if hasattr(node, 'get_neighbors') and callable(node.get_neighbors):
            # BFS for shortest simple path
            path = self._find_simple_path_bfs(node, source, target, max_length)
            return {
                'path': path,
                'source': source,
                'target': target,
                'path_length': len(path) - 1 if path else 0,
                'is_simple': True,
                'status': 'implemented'
            }
        return {
            'path': [],
            'source': source,
            'target': target,
            'path_length': 0,
            'status': 'basic_implementation',
            'note': 'Node does not support graph operations - xwnode graph strategies recommended'
        }

    def _find_simple_path_bfs(self, node: Any, source: str, target: str, max_length: int) -> list:
        """Find simple path using BFS (no cycles)."""
        from collections import deque
        if source == target:
            return [source]
        queue = deque([(source, [source])])
        visited = set()
        while queue:
            current, path = queue.popleft()
            if len(path) > max_length:
                continue
            if current == target:
                return path
            # Mark current as visited in this path context
            visited.add(current)
            try:
                neighbors = list(node.get_neighbors(current))
                for neighbor in neighbors:
                    if neighbor not in path:  # Simple path: no repeated vertices
                        queue.append((neighbor, path + [neighbor]))
            except Exception:
                break
        return []
