#
# Copyright © 2025 Agora
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0, with certain conditions.
# Refer to the "LICENSE" file in the root directory for more information.
#
# pylint: disable=unused-argument
from typing import Callable

from .addon import Addon
from .error import TenError
from .log_level import LogLevel
from .ten_env import ErrorHandler, ResultHandler
from .test import (
    ResultHandler as TestResultHandler,
    ErrorHandler as TestErrorHandler,
)

class _TenError:
    def __new__(
        cls, error_code: int, error_message: str | None
    ) -> "_TenError": ...
    def __str__(self) -> str: ...
    def error_code(self) -> int: ...
    def error_message(self) -> str: ...

class _Msg:
    def get_name(self) -> str: ...
    def set_name(self, name: str) -> None: ...
    def get_source_internal(
        self,
    ) -> tuple[str | None, str | None, str | None]: ...
    def set_dests_internal(
        self,
        locs: list[tuple[str | None, str | None, str | None]],
    ) -> TenError | None: ...
    def set_property_from_json(
        self, path: str | None, json_str: str
    ) -> TenError | None: ...
    def get_property_to_json(
        self, path: str | None = None
    ) -> tuple[str, TenError | None]: ...
    def get_property_int(self, path: str) -> tuple[int, TenError | None]: ...
    def set_property_int(self, path: str, value: int) -> TenError | None: ...
    def get_property_string(self, path: str) -> tuple[str, TenError | None]: ...
    def set_property_string(self, path: str, value: str) -> TenError | None: ...
    def get_property_bool(self, path: str) -> tuple[bool, TenError | None]: ...
    def set_property_bool(self, path: str, value: int) -> TenError | None: ...
    def get_property_float(
        self, path: str
    ) -> tuple[float, TenError | None]: ...
    def set_property_float(
        self, path: str, value: float
    ) -> TenError | None: ...
    def get_property_buf(
        self, path: str
    ) -> tuple[bytearray, TenError | None]: ...
    def set_property_buf(self, path: str, value: bytes) -> TenError | None: ...

class _Cmd(_Msg):
    def __new__(cls, name: str) -> "_Cmd": ...
    def clone(self) -> "_Cmd": ...

class _CmdResult(_Msg):
    def __new__(cls, status_code: int, target_cmd: _Cmd) -> "_CmdResult": ...
    def clone(self) -> "_CmdResult": ...
    def get_status_code(self) -> int: ...
    def set_final(self, is_final: bool) -> None: ...
    def is_final(self) -> bool: ...
    def is_completed(self) -> bool: ...

class _StartGraphCmd(_Cmd):
    def __new__(cls) -> "_StartGraphCmd": ...
    def set_predefined_graph_name(self, predefined_graph_name: str) -> bool: ...
    def set_graph_from_json(self, json_str: str) -> bool: ...

class _StopGraphCmd(_Cmd):
    def __new__(cls) -> "_StopGraphCmd": ...
    def set_graph_id(self, graph_id: str) -> bool: ...

class _TriggerLifeCycleCmd(_Cmd):
    def __new__(cls) -> "_TriggerLifeCycleCmd": ...
    def set_stage(self, stage: str) -> bool: ...

class _Data(_Msg):
    def __new__(cls, name: str) -> "_Data": ...
    def clone(self) -> "_Data": ...
    def alloc_buf(self, size: int) -> None: ...
    def lock_buf(self) -> memoryview: ...
    def unlock_buf(self, buf: memoryview) -> None: ...
    def get_buf(self) -> bytearray: ...

class _VideoFrame(_Msg):
    def __new__(cls, name: str) -> "_VideoFrame": ...
    def clone(self) -> "_VideoFrame": ...
    def alloc_buf(self, size: int) -> None: ...
    def lock_buf(self) -> memoryview: ...
    def unlock_buf(self, buf: memoryview) -> None: ...
    def get_buf(self) -> bytearray: ...
    def get_width(self) -> int: ...
    def set_width(self, width: int) -> None: ...
    def get_height(self) -> int: ...
    def set_height(self, height: int) -> None: ...
    def get_timestamp(self) -> int: ...
    def set_timestamp(self, timestamp: int) -> None: ...
    def get_pixel_fmt(self) -> int: ...
    def set_pixel_fmt(self, pixel_fmt: int) -> None: ...
    def is_eof(self) -> bool: ...
    def set_eof(self, eof: bool) -> None: ...

class _AudioFrame(_Msg):
    def __new__(cls, name: str) -> "_AudioFrame": ...
    def clone(self) -> "_AudioFrame": ...
    def alloc_buf(self, size: int) -> None: ...
    def lock_buf(self) -> memoryview: ...
    def unlock_buf(self, buf: memoryview) -> None: ...
    def get_buf(self) -> bytearray: ...
    def get_timestamp(self) -> int: ...
    def set_timestamp(self, timestamp: int) -> None: ...
    def get_sample_rate(self) -> int: ...
    def set_sample_rate(self, sample_rate: int) -> None: ...
    def get_samples_per_channel(self) -> int: ...
    def set_samples_per_channel(self, samples_per_channel: int) -> None: ...
    def get_bytes_per_sample(self) -> int: ...
    def set_bytes_per_sample(self, bytes_per_sample: int) -> None: ...
    def get_number_of_channels(self) -> int: ...
    def set_number_of_channels(self, number_of_channels: int) -> None: ...
    def get_data_fmt(self) -> int: ...
    def set_data_fmt(self, data_fmt: int) -> None: ...
    def get_line_size(self) -> int: ...
    def set_line_size(self, line_size: int) -> None: ...
    def is_eof(self) -> bool: ...
    def set_eof(self, is_eof: bool) -> None: ...

class _TenEnv:
    @property
    def on_configure_done(self) -> None: ...
    def on_init_done(self) -> None: ...
    def on_start_done(self) -> None: ...
    def on_stop_done(self) -> None: ...
    def on_deinit_done(self) -> None: ...
    def on_create_instance_done(
        self, instance: "_Extension", context: object
    ) -> None: ...
    def get_property_to_json(
        self, path: str | None = None
    ) -> tuple[str, TenError | None]: ...
    def set_property_from_json(
        self, path: str, json_str: str
    ) -> TenError | None: ...
    def get_property_int(self, path: str) -> tuple[int, TenError | None]: ...
    def set_property_int(self, path: str, value: int) -> TenError | None: ...
    def get_property_string(self, path: str) -> tuple[str, TenError | None]: ...
    def set_property_string(self, path: str, value: str) -> TenError | None: ...
    def get_property_bool(self, path: str) -> tuple[bool, TenError | None]: ...
    def set_property_bool(self, path: str, value: int) -> TenError | None: ...
    def get_property_float(
        self, path: str
    ) -> tuple[float, TenError | None]: ...
    def set_property_float(
        self, path: str, value: float
    ) -> TenError | None: ...
    def is_property_exist(self, path: str) -> tuple[bool, TenError | None]: ...
    def init_property_from_json(self, json_str: str) -> TenError | None: ...
    def get_property_to_json_async(
        self,
        path: str | None,
        callback: Callable[[str, TenError | None], None],
    ) -> TenError | None: ...
    def set_property_from_json_async(
        self,
        path: str,
        json_str: str,
        callback: Callable[[TenError | None], None],
    ) -> TenError | None: ...
    def get_property_int_async(
        self, path: str, callback: Callable[[int, TenError | None], None]
    ) -> TenError | None: ...
    def set_property_int_async(
        self,
        path: str,
        value: int,
        callback: Callable[[TenError | None], None],
    ) -> TenError | None: ...
    def get_property_string_async(
        self, path: str, callback: Callable[[str, TenError | None], None]
    ) -> TenError | None: ...
    def set_property_string_async(
        self,
        path: str,
        value: str,
        callback: Callable[[TenError | None], None],
    ) -> TenError | None: ...
    def get_property_bool_async(
        self, path: str, callback: Callable[[bool, TenError | None], None]
    ) -> TenError | None: ...
    def set_property_bool_async(
        self,
        path: str,
        value: int,
        callback: Callable[[TenError | None], None],
    ) -> TenError | None: ...
    def get_property_float_async(
        self, path: str, callback: Callable[[float, TenError | None], None]
    ) -> TenError | None: ...
    def set_property_float_async(
        self,
        path: str,
        value: float,
        callback: Callable[[TenError | None], None],
    ) -> TenError | None: ...
    def is_property_exist_async(
        self, path: str, callback: Callable[[bool, TenError | None], None]
    ) -> TenError | None: ...
    def init_property_from_json_async(
        self, json_str: str, callback: Callable[[TenError | None], None]
    ) -> TenError | None: ...
    def send_cmd(
        self, cmd: _Cmd, result_handler: ResultHandler | None, is_ex: bool
    ) -> TenError | None: ...
    def send_data(
        self, data: _Data, error_handler: ErrorHandler | None
    ) -> TenError | None: ...
    def send_video_frame(
        self, video_frame: _VideoFrame, error_handler: ErrorHandler | None
    ) -> TenError | None: ...
    def send_audio_frame(
        self, audio_frame: _AudioFrame, error_handler: ErrorHandler | None
    ) -> TenError | None: ...
    def return_result(
        self,
        result: _CmdResult,
        error_handler: ErrorHandler | None,
    ) -> TenError | None: ...
    def log(
        self,
        level: LogLevel,
        func_name: str | None,
        file_name: str | None,
        line_no: int,
        category: str | None,
        msg: str,
        sync: bool,
        fields_buf: bytes | None = None,
    ) -> TenError | None: ...

class _App:
    def run_internal(self, run_in_background_flag: bool) -> None: ...
    def wait_internal(self) -> None: ...
    def close_internal(self) -> None: ...

class _Extension:
    def __new__(cls, name: str) -> "_Extension": ...
    def __init__(self, name: str) -> None: ...

class _Addon:
    def on_create_instance_internal(
        self, ten_env: _TenEnv, name: str, context: object
    ) -> None: ...

class _TenEnvTester:
    def on_init_done(self) -> None: ...
    def on_start_done(self) -> None: ...
    def on_stop_done(self) -> None: ...
    def on_deinit_done(self) -> None: ...
    def send_cmd(
        self,
        cmd: _Cmd,
        result_handler: TestResultHandler | None,
        is_ex: bool,
    ) -> TenError | None: ...
    def send_data(
        self, data: _Data, error_handler: TestErrorHandler | None
    ) -> TenError | None: ...
    def send_audio_frame(
        self,
        audio_frame: _AudioFrame,
        error_handler: TestErrorHandler | None,
    ) -> TenError | None: ...
    def send_video_frame(
        self,
        video_frame: _VideoFrame,
        error_handler: TestErrorHandler | None,
    ) -> TenError | None: ...
    def return_result(
        self,
        result: _CmdResult,
        error_handler: TestErrorHandler | None,
    ) -> TenError | None: ...
    def stop_test(self, error: TenError | None) -> TenError | None: ...
    def log(
        self,
        level: LogLevel,
        func_name: str | None,
        file_name: str | None,
        line_no: int,
        category: str | None,
        msg: str,
        sync: bool,
        fields_buf: bytes | None = None,
    ) -> TenError | None: ...

class _ExtensionTester:
    def set_test_mode_single_internal(
        self, addon_name: str, property_json_str: str | None
    ) -> None: ...
    def set_test_mode_graph_internal(self, graph_json: str) -> None: ...
    def set_timeout(self, timeout_us: int) -> None: ...
    def run_internal(self) -> TenError | None: ...

def _ten_py_addon_manager_register_addon_as_extension(
    name: str, base_dir: str | None, instance: Addon, register_ctx: object
) -> None: ...
def _ten_py_addon_manager_add_extension_addon(name: str) -> None: ...
def _ten_py_msg_register_type(cls: type) -> None: ...
def _ten_py_cmd_register_type(cls: type) -> None: ...
def _ten_py_cmd_result_register_type(cls: type) -> None: ...
def _ten_py_cmd_start_graph_register_type(cls: type) -> None: ...
def _ten_py_cmd_stop_graph_register_type(cls: type) -> None: ...
def _ten_py_cmd_trigger_life_cycle_register_type(cls: type) -> None: ...
def _ten_py_data_register_type(cls: type) -> None: ...
def _ten_py_video_frame_register_type(cls: type) -> None: ...
def _ten_py_audio_frame_register_type(cls: type) -> None: ...
def _ten_py_ten_env_register_type(cls: type) -> None: ...
def _ten_py_ten_env_tester_register_type(cls: type) -> None: ...
def _ten_py_error_register_type(cls: type) -> None: ...
