# Copyright 2026 Espressif Systems (Shanghai) Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import time
from enum import Enum
from typing import Any, Dict, Optional


class CommandType(Enum):
    """Commands sent from Frontend to Backend."""

    CONNECT = 1
    DISCONNECT = 2
    SET_PARAM = 3
    GET_PARAM = 4
    START_STREAM = 5
    STOP_STREAM = 6
    FETCH_PROFILE = 7
    WRITE_DATA = 8
    SET_IO_LOGGING = 9
    DOWNLOAD_FIRMWARE = 10
    FLASH_FIRMWARE = 11
    GET_CHIP_INFO = 12
    GET_PARTITION_TABLE = 13
    GET_APP_INFO = 14
    LIST_PORTS = 15
    RESET_STATE = 16
    READ_FIRMWARE = 17
    BACKUP_FIRMWARE = 18


class EventType(Enum):
    """Events sent from Backend to Frontend."""

    STATUS_CHANGED = 1
    LOG_MSG = 2
    PARAM_ACK = 3
    STREAM_DATA = 4
    ERROR = 5
    IO_DATA = 6
    PARAM_UPDATE = 7
    PROFILE_UPDATED = 8
    TEXT_STREAM = 9
    IO_LOG_STATUS = 10
    FIRMWARE_PROGRESS = 11
    CHIP_INFO_RECEIVED = 12
    PARTITION_TABLE_RECEIVED = 13
    APP_INFO_RECEIVED = 14
    STREAM_STATUS = 15
    PORTS_LISTED = 16
    FIRMWARE_READ_COMPLETE = 17


class Packet:
    """Base packet structure for IPC."""

    def __init__(self, type_enum: Enum, payload: Dict[str, Any] = None):
        self.type = type_enum
        self.payload = payload or {}
        self.timestamp = time.time()

    def to_dict(self) -> Dict[str, Any]:
        return {
            "type": self.type.name,
            "payload": self.payload,
            "timestamp": self.timestamp,
        }

    @staticmethod
    def from_dict(data: Dict[str, Any], enum_cls) -> "Packet":
        pkt = Packet(enum_cls[data["type"]], data.get("payload"))
        pkt.timestamp = data.get("timestamp", time.time())
        return pkt


class LogLevel(Enum):
    INFO = "INFO"
    WARNING = "WARN"
    ERROR = "ERROR"
    DEBUG = "DEBUG"


class JsonRpc:
    """Helper for JSON-RPC 2.0 protocol."""

    @staticmethod
    def create_request(
        method: str, params: Dict[str, Any] = None, req_id: Any = None
    ) -> Dict[str, Any]:
        """Create a JSON-RPC request object."""
        req = {"jsonrpc": "2.0", "method": method, "params": params or {}}
        if req_id is not None:
            req["id"] = req_id
        return req

    @staticmethod
    def create_response(
        req_id: Any, result: Any = None, error: Dict[str, Any] = None
    ) -> Dict[str, Any]:
        """Create a JSON-RPC response object."""
        res = {"jsonrpc": "2.0", "id": req_id}
        if error:
            res["error"] = error
            res["result"] = None
        else:
            res["result"] = result
            res["error"] = None
        return res

    @staticmethod
    def parse(data: Dict[str, Any]) -> Dict[str, Any]:
        """Parse incoming JSON-RPC message."""
        # Ideally validation happens here
        return data
