"""Protobuf 配置处理工具

由于 TrailBase 配置 API 使用 protobuf 格式，此模块提供基本的 protobuf 处理功能。
注意：这是一个简化实现，仅支持配置更新所需的基本操作。
"""

import base64
import struct
from typing import Any


def decode_varint(data: bytes, offset: int = 0) -> tuple[int, int]:
    """解码 protobuf varint"""
    result = 0
    shift = 0
    pos = offset
    while pos < len(data):
        byte = data[pos]
        result |= (byte & 0x7F) << shift
        pos += 1
        if (byte & 0x80) == 0:
            break
        shift += 7
    return result, pos


def encode_varint(value: int) -> bytes:
    """编码 protobuf varint"""
    result = bytearray()
    while value > 0x7F:
        result.append((value & 0x7F) | 0x80)
        value >>= 7
    result.append(value & 0x7F)
    return bytes(result)


def encode_field(field_number: int, wire_type: int, value: bytes) -> bytes:
    """编码 protobuf 字段"""
    tag = (field_number << 3) | wire_type
    return encode_varint(tag) + value


def encode_string(field_number: int, value: str) -> bytes:
    """编码字符串字段"""
    value_bytes = value.encode("utf-8")
    return encode_field(field_number, 2, encode_varint(len(value_bytes)) + value_bytes)


def encode_int32(field_number: int, value: int) -> bytes:
    """编码 int32 字段"""
    return encode_field(field_number, 0, encode_varint(value))


def encode_bool(field_number: int, value: bool) -> bytes:
    """编码 bool 字段"""
    return encode_field(field_number, 0, encode_varint(1 if value else 0))


def encode_message(field_number: int, message: bytes) -> bytes:
    """编码嵌套消息字段"""
    return encode_field(field_number, 2, encode_varint(len(message)) + message)


def parse_get_config_response(data: bytes) -> dict[str, Any]:
    """解析 GetConfigResponse protobuf 消息
    
    返回格式: {"config": {...}, "hash": "..."}
    注意：这是一个简化实现，仅解析 hash 字段
    """
    result: dict[str, Any] = {}
    pos = 0
    
    while pos < len(data):
        tag, pos = decode_varint(data, pos)
        field_number = tag >> 3
        wire_type = tag & 0x7
        
        if wire_type == 0:  # Varint
            value, pos = decode_varint(data, pos)
            if field_number == 2:  # hash
                # hash 是字符串，需要特殊处理
                # 实际上 hash 字段在 protobuf 中是字符串类型（wire_type=2）
                pass
        elif wire_type == 2:  # Length-delimited
            length, pos = decode_varint(data, pos)
            value_bytes = data[pos : pos + length]
            pos += length
            
            if field_number == 1:  # config (嵌套消息)
                # 配置是嵌套消息，这里我们只返回原始数据
                result["config"] = {"_raw": value_bytes.hex()}
            elif field_number == 2:  # hash (字符串)
                try:
                    result["hash"] = value_bytes.decode("utf-8")
                except UnicodeDecodeError:
                    result["hash"] = base64.urlsafe_b64encode(value_bytes).decode("utf-8")
    
    return result


def build_update_config_request(config_patch: dict[str, Any], hash_value: str) -> bytes:
    """构建 UpdateConfigRequest protobuf 消息
    
    Args:
        config_patch: 配置补丁，包含要更新的字段
        hash_value: 配置 hash
    
    Returns:
        protobuf 编码的二进制数据
    """
    # 这是一个非常简化的实现
    # 实际上需要完整实现 Config 消息的编码
    # 由于复杂度较高，这里返回一个占位符
    # 实际使用时需要完整的 protobuf 实现
    
    # 构建 Config 消息（简化版，仅包含 jobs 字段）
    config_bytes = bytearray()
    
    if "jobs" in config_patch:
        jobs_config = config_patch["jobs"]
        if "system_jobs" in jobs_config:
            # 编码 JobsConfig.system_jobs (field 1, repeated SystemJob)
            for job in jobs_config["system_jobs"]:
                job_bytes = bytearray()
                
                # SystemJob.id (field 1, int32)
                if "id" in job:
                    job_bytes.extend(encode_int32(1, job["id"]))
                
                # SystemJob.schedule (field 2, string)
                if "schedule" in job:
                    job_bytes.extend(encode_string(2, job["schedule"]))
                
                # SystemJob.disabled (field 3, bool)
                if "disabled" in job:
                    job_bytes.extend(encode_bool(3, job["disabled"]))
                
                # 编码为嵌套消息
                config_bytes.extend(encode_message(5, bytes(job_bytes)))  # Config.jobs (field 5)
    
    # 构建 UpdateConfigRequest
    request_bytes = bytearray()
    
    # UpdateConfigRequest.config (field 1, Config)
    if config_bytes:
        request_bytes.extend(encode_message(1, bytes(config_bytes)))
    
    # UpdateConfigRequest.hash (field 2, string)
    if hash_value:
        request_bytes.extend(encode_string(2, hash_value))
    
    return bytes(request_bytes)

