import typing

from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gst
from typing_extensions import Self

T = typing.TypeVar("T")

MIKEY_VERSION: int = 1
SDP_BWTYPE_AS: str = "AS"
SDP_BWTYPE_CT: str = "CT"
SDP_BWTYPE_EXT_PREFIX: str = "X-"
SDP_BWTYPE_RR: str = "RR"
SDP_BWTYPE_RS: str = "RS"
SDP_BWTYPE_TIAS: str = "TIAS"

def sdp_address_is_multicast(nettype: str, addrtype: str, addr: str) -> bool: ...
def sdp_make_keymgmt(uri: str, base64: str) -> str: ...
def sdp_media_init() -> typing.Tuple[SDPResult, SDPMedia]: ...
def sdp_media_new() -> typing.Tuple[SDPResult, SDPMedia]: ...
def sdp_media_set_media_from_caps(
    caps: Gst.Caps,
) -> typing.Tuple[SDPResult, SDPMedia]: ...
def sdp_message_as_uri(scheme: str, msg: SDPMessage) -> str: ...
def sdp_message_init() -> typing.Tuple[SDPResult, SDPMessage]: ...
def sdp_message_new() -> typing.Tuple[SDPResult, SDPMessage]: ...
def sdp_message_new_from_text(text: str) -> typing.Tuple[SDPResult, SDPMessage]: ...
def sdp_message_parse_buffer(
    data: typing.Sequence[int], msg: SDPMessage
) -> SDPResult: ...
def sdp_message_parse_uri(uri: str, msg: SDPMessage) -> SDPResult: ...

class MIKEYDecryptInfo(GObject.GPointer): ...
class MIKEYEncryptInfo(GObject.GPointer): ...

class MIKEYMapSRTP(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYMapSRTP()
    """

    policy: int = ...
    ssrc: int = ...
    roc: int = ...

class MIKEYMessage(GObject.GBoxed):
    """
    :Constructors:

    ::

        MIKEYMessage()
        new() -> GstSdp.MIKEYMessage
        new_from_bytes(bytes:GLib.Bytes, info:GstSdp.MIKEYDecryptInfo) -> GstSdp.MIKEYMessage
        new_from_caps(caps:Gst.Caps) -> GstSdp.MIKEYMessage or None
        new_from_data(data:list, info:GstSdp.MIKEYDecryptInfo) -> GstSdp.MIKEYMessage
    """

    mini_object: Gst.MiniObject = ...
    version: int = ...
    type: MIKEYType = ...
    V: bool = ...
    prf_func: MIKEYPRFFunc = ...
    CSB_id: int = ...
    map_type: MIKEYMapType = ...
    map_info: list[None] = ...
    payloads: list[None] = ...
    @staticmethod
    def __new__(cls: type[Self]) -> Self: ...
    def add_cs_srtp(self, policy: int, ssrc: int, roc: int) -> bool: ...
    def add_payload(self, payload: MIKEYPayload) -> bool: ...
    def add_pke(self, C: MIKEYCacheType, data: typing.Sequence[int]) -> bool: ...
    def add_rand(self, rand: typing.Sequence[int]) -> bool: ...
    def add_rand_len(self, len: int) -> bool: ...
    def add_t(self, type: MIKEYTSType, ts_value: typing.Sequence[int]) -> bool: ...
    def add_t_now_ntp_utc(self) -> bool: ...
    def base64_encode(self) -> str: ...
    def find_payload(
        self, type: MIKEYPayloadType, nth: int
    ) -> typing.Optional[MIKEYPayload]: ...
    def get_cs_srtp(self, idx: int) -> typing.Optional[MIKEYMapSRTP]: ...
    def get_n_cs(self) -> int: ...
    def get_n_payloads(self) -> int: ...
    def get_payload(self, idx: int) -> typing.Optional[MIKEYPayload]: ...
    def insert_cs_srtp(self, idx: int, map: MIKEYMapSRTP) -> bool: ...
    def insert_payload(self, idx: int, payload: MIKEYPayload) -> bool: ...
    @classmethod
    def new(cls) -> MIKEYMessage: ...
    @classmethod
    def new_from_bytes(
        cls, bytes: GLib.Bytes, info: MIKEYDecryptInfo
    ) -> MIKEYMessage: ...
    @classmethod
    def new_from_caps(cls, caps: Gst.Caps) -> typing.Optional[MIKEYMessage]: ...
    @classmethod
    def new_from_data(
        cls, data: typing.Sequence[int], info: MIKEYDecryptInfo
    ) -> MIKEYMessage: ...
    def remove_cs_srtp(self, idx: int) -> bool: ...
    def remove_payload(self, idx: int) -> bool: ...
    def replace_cs_srtp(self, idx: int, map: MIKEYMapSRTP) -> bool: ...
    def replace_payload(self, idx: int, payload: MIKEYPayload) -> bool: ...
    def set_info(
        self,
        version: int,
        type: MIKEYType,
        V: bool,
        prf_func: MIKEYPRFFunc,
        CSB_id: int,
        map_type: MIKEYMapType,
    ) -> bool: ...
    def to_bytes(self, info: MIKEYEncryptInfo) -> GLib.Bytes: ...
    def to_caps(self, caps: Gst.Caps) -> bool: ...

class MIKEYPayload(GObject.GBoxed):
    """
    :Constructors:

    ::

        MIKEYPayload()
        new(type:GstSdp.MIKEYPayloadType) -> GstSdp.MIKEYPayload or None
    """

    mini_object: Gst.MiniObject = ...
    type: MIKEYPayloadType = ...
    len: int = ...
    def kemac_add_sub(self, newpay: MIKEYPayload) -> bool: ...
    def kemac_get_n_sub(self) -> int: ...
    def kemac_get_sub(self, idx: int) -> typing.Optional[MIKEYPayload]: ...
    def kemac_remove_sub(self, idx: int) -> bool: ...
    def kemac_set(self, enc_alg: MIKEYEncAlg, mac_alg: MIKEYMacAlg) -> bool: ...
    def key_data_set_interval(
        self, vf_data: typing.Sequence[int], vt_data: typing.Sequence[int]
    ) -> bool: ...
    def key_data_set_key(
        self, key_type: MIKEYKeyDataType, key_data: typing.Sequence[int]
    ) -> bool: ...
    def key_data_set_salt(
        self, salt_data: typing.Optional[typing.Sequence[int]] = None
    ) -> bool: ...
    def key_data_set_spi(self, spi_data: typing.Sequence[int]) -> bool: ...
    @classmethod
    def new(cls, type: MIKEYPayloadType) -> typing.Optional[MIKEYPayload]: ...
    def pke_set(self, C: MIKEYCacheType, data: typing.Sequence[int]) -> bool: ...
    def rand_set(self, rand: typing.Sequence[int]) -> bool: ...
    def sp_add_param(self, type: int, val: typing.Sequence[int]) -> bool: ...
    def sp_get_n_params(self) -> int: ...
    def sp_get_param(self, idx: int) -> typing.Optional[MIKEYPayloadSPParam]: ...
    def sp_remove_param(self, idx: int) -> bool: ...
    def sp_set(self, policy: int, proto: MIKEYSecProto) -> bool: ...
    def t_set(self, type: MIKEYTSType, ts_value: typing.Sequence[int]) -> bool: ...

class MIKEYPayloadKEMAC(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadKEMAC()
    """

    pt: MIKEYPayload = ...
    enc_alg: MIKEYEncAlg = ...
    mac_alg: MIKEYMacAlg = ...
    subpayloads: list[None] = ...

class MIKEYPayloadKeyData(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadKeyData()
    """

    pt: MIKEYPayload = ...
    key_type: MIKEYKeyDataType = ...
    key_len: int = ...
    key_data: int = ...
    salt_len: int = ...
    salt_data: int = ...
    kv_type: MIKEYKVType = ...
    kv_len: bytes = ...
    kv_data: bytes = ...

class MIKEYPayloadPKE(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadPKE()
    """

    pt: MIKEYPayload = ...
    C: MIKEYCacheType = ...
    data_len: int = ...
    data: int = ...

class MIKEYPayloadRAND(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadRAND()
    """

    pt: MIKEYPayload = ...
    len: int = ...
    rand: int = ...

class MIKEYPayloadSP(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadSP()
    """

    pt: MIKEYPayload = ...
    policy: int = ...
    proto: MIKEYSecProto = ...
    params: list[None] = ...

class MIKEYPayloadSPParam(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadSPParam()
    """

    type: int = ...
    len: int = ...
    val: int = ...

class MIKEYPayloadT(GObject.GPointer):
    """
    :Constructors:

    ::

        MIKEYPayloadT()
    """

    pt: MIKEYPayload = ...
    type: MIKEYTSType = ...
    ts_value: int = ...

class SDPAttribute(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPAttribute()
    """

    key: str = ...
    value: str = ...
    def clear(self) -> SDPResult: ...
    def set(self, key: str, value: typing.Optional[str] = None) -> SDPResult: ...

class SDPBandwidth(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPBandwidth()
    """

    bwtype: str = ...
    bandwidth: int = ...
    def clear(self) -> SDPResult: ...
    def set(self, bwtype: str, bandwidth: int) -> SDPResult: ...

class SDPConnection(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPConnection()
    """

    nettype: str = ...
    addrtype: str = ...
    address: str = ...
    ttl: int = ...
    addr_number: int = ...
    def clear(self) -> SDPResult: ...
    def set(
        self, nettype: str, addrtype: str, address: str, ttl: int, addr_number: int
    ) -> SDPResult: ...

class SDPKey(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPKey()
    """

    type: str = ...
    data: str = ...

class SDPMedia(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPMedia()
    """

    media: str = ...
    port: int = ...
    num_ports: int = ...
    proto: str = ...
    fmts: list[None] = ...
    information: str = ...
    connections: list[None] = ...
    bandwidths: list[None] = ...
    key: SDPKey = ...
    attributes: list[None] = ...
    def add_attribute(
        self, key: str, value: typing.Optional[str] = None
    ) -> SDPResult: ...
    def add_bandwidth(self, bwtype: str, bandwidth: int) -> SDPResult: ...
    def add_connection(
        self, nettype: str, addrtype: str, address: str, ttl: int, addr_number: int
    ) -> SDPResult: ...
    def add_format(self, format: str) -> SDPResult: ...
    def as_text(self) -> str: ...
    def attributes_len(self) -> int: ...
    def attributes_to_caps(self, caps: Gst.Caps) -> SDPResult: ...
    def bandwidths_len(self) -> int: ...
    def connections_len(self) -> int: ...
    def copy(self) -> typing.Tuple[SDPResult, SDPMedia]: ...
    def formats_len(self) -> int: ...
    def free(self) -> SDPResult: ...
    def get_attribute(self, idx: int) -> SDPAttribute: ...
    def get_attribute_val(self, key: str) -> typing.Optional[str]: ...
    def get_attribute_val_n(self, key: str, nth: int) -> typing.Optional[str]: ...
    def get_bandwidth(self, idx: int) -> SDPBandwidth: ...
    def get_caps_from_media(self, pt: int) -> typing.Optional[Gst.Caps]: ...
    def get_connection(self, idx: int) -> SDPConnection: ...
    def get_format(self, idx: int) -> str: ...
    def get_information(self) -> str: ...
    def get_key(self) -> SDPKey: ...
    def get_media(self) -> str: ...
    def get_num_ports(self) -> int: ...
    def get_port(self) -> int: ...
    def get_proto(self) -> str: ...
    @staticmethod
    def init() -> typing.Tuple[SDPResult, SDPMedia]: ...
    def insert_attribute(self, idx: int, attr: SDPAttribute) -> SDPResult: ...
    def insert_bandwidth(self, idx: int, bw: SDPBandwidth) -> SDPResult: ...
    def insert_connection(self, idx: int, conn: SDPConnection) -> SDPResult: ...
    def insert_format(self, idx: int, format: str) -> SDPResult: ...
    @staticmethod
    def new() -> typing.Tuple[SDPResult, SDPMedia]: ...
    def parse_keymgmt(self) -> typing.Tuple[SDPResult, MIKEYMessage]: ...
    def remove_attribute(self, idx: int) -> SDPResult: ...
    def remove_bandwidth(self, idx: int) -> SDPResult: ...
    def remove_connection(self, idx: int) -> SDPResult: ...
    def remove_format(self, idx: int) -> SDPResult: ...
    def replace_attribute(self, idx: int, attr: SDPAttribute) -> SDPResult: ...
    def replace_bandwidth(self, idx: int, bw: SDPBandwidth) -> SDPResult: ...
    def replace_connection(self, idx: int, conn: SDPConnection) -> SDPResult: ...
    def replace_format(self, idx: int, format: str) -> SDPResult: ...
    def set_information(self, information: str) -> SDPResult: ...
    def set_key(self, type: str, data: str) -> SDPResult: ...
    def set_media(self, med: str) -> SDPResult: ...
    @staticmethod
    def set_media_from_caps(caps: Gst.Caps) -> typing.Tuple[SDPResult, SDPMedia]: ...
    def set_port_info(self, port: int, num_ports: int) -> SDPResult: ...
    def set_proto(self, proto: str) -> SDPResult: ...
    def uninit(self) -> SDPResult: ...

class SDPMessage(GObject.GBoxed):
    """
    :Constructors:

    ::

        SDPMessage()
    """

    version: str = ...
    origin: SDPOrigin = ...
    session_name: str = ...
    information: str = ...
    uri: str = ...
    emails: list[None] = ...
    phones: list[None] = ...
    connection: SDPConnection = ...
    bandwidths: list[None] = ...
    times: list[None] = ...
    zones: list[None] = ...
    key: SDPKey = ...
    attributes: list[None] = ...
    medias: list[None] = ...
    def add_attribute(
        self, key: str, value: typing.Optional[str] = None
    ) -> SDPResult: ...
    def add_bandwidth(self, bwtype: str, bandwidth: int) -> SDPResult: ...
    def add_email(self, email: str) -> SDPResult: ...
    def add_media(self, media: SDPMedia) -> SDPResult: ...
    def add_phone(self, phone: str) -> SDPResult: ...
    def add_time(
        self, start: str, stop: str, repeat: typing.Sequence[str]
    ) -> SDPResult: ...
    def add_zone(self, adj_time: str, typed_time: str) -> SDPResult: ...
    def as_text(self) -> str: ...
    @staticmethod
    def as_uri(scheme: str, msg: SDPMessage) -> str: ...
    def attributes_len(self) -> int: ...
    def attributes_to_caps(self, caps: Gst.Caps) -> SDPResult: ...
    def bandwidths_len(self) -> int: ...
    def copy(self) -> typing.Tuple[SDPResult, SDPMessage]: ...
    def dump(self) -> SDPResult: ...
    def emails_len(self) -> int: ...
    def free(self) -> SDPResult: ...
    def get_attribute(self, idx: int) -> SDPAttribute: ...
    def get_attribute_val(self, key: str) -> typing.Optional[str]: ...
    def get_attribute_val_n(self, key: str, nth: int) -> typing.Optional[str]: ...
    def get_bandwidth(self, idx: int) -> SDPBandwidth: ...
    def get_connection(self) -> SDPConnection: ...
    def get_email(self, idx: int) -> str: ...
    def get_information(self) -> str: ...
    def get_key(self) -> SDPKey: ...
    def get_media(self, idx: int) -> SDPMedia: ...
    def get_origin(self) -> SDPOrigin: ...
    def get_phone(self, idx: int) -> str: ...
    def get_session_name(self) -> str: ...
    def get_time(self, idx: int) -> SDPTime: ...
    def get_uri(self) -> str: ...
    def get_version(self) -> str: ...
    def get_zone(self, idx: int) -> SDPZone: ...
    @staticmethod
    def init() -> typing.Tuple[SDPResult, SDPMessage]: ...
    def insert_attribute(self, idx: int, attr: SDPAttribute) -> SDPResult: ...
    def insert_bandwidth(self, idx: int, bw: SDPBandwidth) -> SDPResult: ...
    def insert_email(self, idx: int, email: str) -> SDPResult: ...
    def insert_phone(self, idx: int, phone: str) -> SDPResult: ...
    def insert_time(self, idx: int, t: SDPTime) -> SDPResult: ...
    def insert_zone(self, idx: int, zone: SDPZone) -> SDPResult: ...
    def medias_len(self) -> int: ...
    @staticmethod
    def new() -> typing.Tuple[SDPResult, SDPMessage]: ...
    @staticmethod
    def new_from_text(text: str) -> typing.Tuple[SDPResult, SDPMessage]: ...
    @staticmethod
    def parse_buffer(data: typing.Sequence[int], msg: SDPMessage) -> SDPResult: ...
    def parse_keymgmt(self) -> typing.Tuple[SDPResult, MIKEYMessage]: ...
    @staticmethod
    def parse_uri(uri: str, msg: SDPMessage) -> SDPResult: ...
    def phones_len(self) -> int: ...
    def remove_attribute(self, idx: int) -> SDPResult: ...
    def remove_bandwidth(self, idx: int) -> SDPResult: ...
    def remove_email(self, idx: int) -> SDPResult: ...
    def remove_media(self, idx: int) -> SDPResult: ...
    def remove_phone(self, idx: int) -> SDPResult: ...
    def remove_time(self, idx: int) -> SDPResult: ...
    def remove_zone(self, idx: int) -> SDPResult: ...
    def replace_attribute(self, idx: int, attr: SDPAttribute) -> SDPResult: ...
    def replace_bandwidth(self, idx: int, bw: SDPBandwidth) -> SDPResult: ...
    def replace_email(self, idx: int, email: str) -> SDPResult: ...
    def replace_phone(self, idx: int, phone: str) -> SDPResult: ...
    def replace_time(self, idx: int, t: SDPTime) -> SDPResult: ...
    def replace_zone(self, idx: int, zone: SDPZone) -> SDPResult: ...
    def set_connection(
        self, nettype: str, addrtype: str, address: str, ttl: int, addr_number: int
    ) -> SDPResult: ...
    def set_information(self, information: str) -> SDPResult: ...
    def set_key(self, type: str, data: str) -> SDPResult: ...
    def set_origin(
        self,
        username: str,
        sess_id: str,
        sess_version: str,
        nettype: str,
        addrtype: str,
        addr: str,
    ) -> SDPResult: ...
    def set_session_name(self, session_name: str) -> SDPResult: ...
    def set_uri(self, uri: str) -> SDPResult: ...
    def set_version(self, version: str) -> SDPResult: ...
    def times_len(self) -> int: ...
    def uninit(self) -> SDPResult: ...
    def zones_len(self) -> int: ...

class SDPOrigin(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPOrigin()
    """

    username: str = ...
    sess_id: str = ...
    sess_version: str = ...
    nettype: str = ...
    addrtype: str = ...
    addr: str = ...

class SDPTime(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPTime()
    """

    start: str = ...
    stop: str = ...
    repeat: list[None] = ...
    def clear(self) -> SDPResult: ...
    def set(self, start: str, stop: str, repeat: typing.Sequence[str]) -> SDPResult: ...

class SDPZone(GObject.GPointer):
    """
    :Constructors:

    ::

        SDPZone()
    """

    time: str = ...
    typed_time: str = ...
    def clear(self) -> SDPResult: ...
    def set(self, adj_time: str, typed_time: str) -> SDPResult: ...

class MIKEYCacheType(GObject.GEnum):
    ALWAYS = 1
    FOR_CSB = 2
    NONE = 0

class MIKEYEncAlg(GObject.GEnum):
    AES_CM_128 = 1
    AES_GCM_128 = 6
    AES_KW_128 = 2
    NULL = 0

class MIKEYKVType(GObject.GEnum):
    INTERVAL = 2
    NULL = 0
    SPI = 1

class MIKEYKeyDataType(GObject.GEnum):
    TEK = 2
    TGK = 0

class MIKEYMacAlg(GObject.GEnum):
    HMAC_SHA_1_160 = 1
    NULL = 0

class MIKEYMapType(GObject.GEnum):
    MIKEY_MAP_TYPE_SRTP = 0

class MIKEYPRFFunc(GObject.GEnum):
    MIKEY_PRF_MIKEY_1 = 0

class MIKEYPayloadType(GObject.GEnum):
    CERT = 7
    CHASH = 8
    DH = 3
    ERR = 12
    GEN_EXT = 21
    ID = 6
    KEMAC = 1
    KEY_DATA = 20
    LAST = 0
    PKE = 2
    RAND = 11
    SIGN = 4
    SP = 10
    T = 5
    V = 9

class MIKEYSecProto(GObject.GEnum):
    MIKEY_SEC_PROTO_SRTP = 0

class MIKEYSecSRTP(GObject.GEnum):
    AEAD_AUTH_TAG_LEN = 20
    AUTH_ALG = 2
    AUTH_KEY_LEN = 3
    AUTH_TAG_LEN = 11
    ENC_ALG = 0
    ENC_KEY_LEN = 1
    FEC_ORDER = 9
    KEY_DERIV_RATE = 6
    PRF = 5
    SALT_KEY_LEN = 4
    SRTCP_ENC = 8
    SRTP_AUTH = 10
    SRTP_ENC = 7
    SRTP_PREFIX_LEN = 12

class MIKEYTSType(GObject.GEnum):
    COUNTER = 2
    NTP = 1
    NTP_UTC = 0

class MIKEYType(GObject.GEnum):
    DH_INIT = 4
    DH_RESP = 5
    ERROR = 6
    INVALID = -1
    PK_INIT = 2
    PK_VERIFY = 3
    PSK_INIT = 0
    PSK_VERIFY = 1

class SDPResult(GObject.GEnum):
    EINVAL = -1
    OK = 0
