"""
Robot Framework Listener that reports step (test) start/end events
to the Desktop Agent via a local HTTP callback.

Usage:
  robot --listener step_listener.py:http://127.0.0.1:PORT:EXECUTION_ID script.robot

The listener maps Robot Framework "tests" to automation "steps".
Each test in the .robot file corresponds to one step in the checkpoint system.
"""

import json
import urllib.request
import urllib.error
import traceback


class step_listener:
    ROBOT_LISTENER_API_VERSION = 3

    def __init__(self, callback_url: str, execution_id: str):
        self.callback_url = callback_url
        self.execution_id = execution_id
        self._step_outputs = {}

    def start_test(self, data, result):
        """Called when a test (step) starts."""
        self._post_event({
            "executionId": self.execution_id,
            "stepId": data.name,
            "status": "running",
        })

    def end_test(self, data, result):
        """Called when a test (step) ends."""
        # Collect output variables that start with IDEMPOTENCY_
        output = {}
        try:
            from robot.libraries.BuiltIn import BuiltIn
            bi = BuiltIn()
            # Try to get any variables set during the test
            for var_name in list(bi.get_variables().keys()):
                if "IDEMPOTENCY_" in str(var_name).upper():
                    clean_name = str(var_name).strip("${}")
                    output[clean_name] = str(bi.get_variable_value(var_name))
        except Exception:
            pass

        event = {
            "executionId": self.execution_id,
            "stepId": data.name,
            "status": "completed" if result.passed else "failed",
        }

        if not result.passed:
            event["error"] = str(result.message)

        if output:
            event["output"] = output

        self._post_event(event)

    def _post_event(self, event: dict):
        """Send event to the agent's local callback server."""
        try:
            data = json.dumps(event).encode("utf-8")
            req = urllib.request.Request(
                f"{self.callback_url}/step",
                data=data,
                headers={"Content-Type": "application/json"},
                method="POST",
            )
            urllib.request.urlopen(req, timeout=5)
        except Exception as e:
            # Don't fail the test if reporting fails
            print(f"[StepListener] Warning: Failed to report step event: {e}")
