from pathlib import Path
from threading import Lock

from task.states.base import TaskStateBase
from task.errors import TaskCallbackFailedError

log_lock = Lock()


class TaskErrorState(TaskStateBase):
    @property
    def name(self):
        return "error"

    def run(self):
        self._task.logger.info("Calculation went to error state")

        # Get the log file path and read its content
        log_file_path = Path(self._task.log_file_handler.baseFilename)
        log_content = log_file_path.read_text()

        # Truncate the log if it exceeds the maximum allowed size (20,000 characters)
        if len(log_content) > 20000:
            truncated_log = f"{log_content[:10000]}\n...\n...\n...\n{log_content[-10000:]}"
        else:
            truncated_log = log_content

        # Attempt to send callbacks with the error and log information
        try:
            self._task.send_callbacks(
                {"error": "Calculation went to error state", "log": truncated_log}
            )
        except TaskCallbackFailedError as exception:
            self._task.logger.critical("Cannot send callback")
            self._task.logger.exception(exception)

        self._task.set_finished(True)

        # Safely remove log handler and delete the log file
        with log_lock:
            try:
                # Remove the log file handler from the logger
                self._task.logger.logger.handlers.remove(self._task.log_file_handler)
                if log_file_path.exists():
                    log_file_path.unlink()  # Delete the log file
            except (OSError, ValueError) as exc:
                self._task.logger.warning(f"Cannot safely remove or delete the log file: {exc}")
