"""Constants for memory analysis symbol pattern matching."""

import re

# Pattern to extract ESPHome component namespaces dynamically
ESPHOME_COMPONENT_PATTERN = re.compile(r"esphome::([a-zA-Z0-9_]+)::")

# Section mapping for ELF file sections
# Maps standard section names to their various platform-specific variants
# Note: Order matters! More specific patterns (.bss) must come before general ones (.dram)
# because ESP-IDF uses names like ".dram0.bss" which would match ".dram" otherwise
#
# Platform-specific sections:
# - ESP8266/ESP32: .iram*, .dram*
# - LibreTiny RTL87xx: .xip.code_* (flash), .ram.code_* (RAM)
# - LibreTiny BK7231: .itcm.code (fast RAM), .vectors (interrupt vectors)
# - LibreTiny LN882X: .flash_text, .flash_copy* (flash code)
# - Zephyr/nRF52: text, rodata, datas, bss (no leading dots)
SECTION_MAPPING = {
    ".text": frozenset(
        [
            ".text",
            ".iram",
            # LibreTiny RTL87xx XIP (eXecute In Place) flash code
            ".xip.code",
            # LibreTiny RTL87xx RAM code
            ".ram.code_text",
            # LibreTiny BK7231 fast RAM code and vectors
            ".itcm.code",
            ".vectors",
            # LibreTiny LN882X flash code
            ".flash_text",
            ".flash_copy",
            # Zephyr/nRF52 sections (no leading dots)
            "text",
            "rom_start",
        ]
    ),
    ".rodata": frozenset(
        [
            ".rodata",
            # LibreTiny RTL87xx read-only data in RAM
            ".ram.code_rodata",
            # Zephyr/nRF52 sections (no leading dots)
            "rodata",
        ]
    ),
    # .bss patterns - must be before .data to catch ".dram0.bss"
    ".bss": frozenset(
        [
            ".bss",
            # LibreTiny LN882X BSS
            ".bss_ram",
            # Zephyr/nRF52 sections (no leading dots)
            "bss",
            "noinit",
        ]
    ),
    ".data": frozenset(
        [
            ".data",
            ".dram",
            # Zephyr/nRF52 sections (no leading dots)
            "datas",
        ]
    ),
}

# Component identification rules
# Symbol patterns: patterns found in raw symbol names
SYMBOL_PATTERNS = {
    "freertos": [
        "vTask",
        "xTask",
        "xQueue",
        "pvPort",
        "vPort",
        "uxTask",
        "pcTask",
        "prvTimerTask",
        "prvAddNewTaskToReadyList",
        "pxReadyTasksLists",
        "prvAddCurrentTaskToDelayedList",
        "xEventGroupWaitBits",
        "xRingbufferSendFromISR",
        "prvSendItemDoneNoSplit",
        "prvReceiveGeneric",
        "prvSendAcquireGeneric",
        "prvCopyItemAllowSplit",
        "xEventGroup",
        "xRingbuffer",
        "prvSend",
        "prvReceive",
        "prvCopy",
        "xPort",
        "ulTaskGenericNotifyTake",
        "prvIdleTask",
        "prvInitialiseNewTask",
        "prvIsYieldRequiredSMP",
        "prvGetItemByteBuf",
        "prvInitializeNewRingbuffer",
        "prvAcquireItemNoSplit",
        "prvNotifyQueueSetContainer",
        "ucStaticTimerQueueStorage",
        "eTaskGetState",
        "main_task",
        "do_system_init_fn",
        "xSemaphoreCreateGenericWithCaps",
        "vListInsert",
        "uxListRemove",
        "vRingbufferReturnItem",
        "vRingbufferReturnItemFromISR",
        "prvCheckItemFitsByteBuffer",
        "prvGetCurMaxSizeAllowSplit",
        "tick_hook",
        "sys_sem_new",
        "sys_arch_mbox_fetch",
        "sys_arch_sem_wait",
        "prvDeleteTCB",
        "vQueueDeleteWithCaps",
        "vRingbufferDeleteWithCaps",
        "vSemaphoreDeleteWithCaps",
        "prvCheckItemAvail",
        "prvCheckTaskCanBeScheduledSMP",
        "prvGetCurMaxSizeNoSplit",
        "prvResetNextTaskUnblockTime",
        "prvReturnItemByteBuf",
        "vApplicationStackOverflowHook",
        "vApplicationGetIdleTaskMemory",
        "sys_init",
        "sys_mbox_new",
        "sys_arch_mbox_tryfetch",
    ],
    # LibreTiny/Beken BK7231 radio calibration
    "bk_radio_cal": [
        "bk7011_",
        "calibration_main",
        "gcali_",
        "rwnx_cal",
    ],
    # LibreTiny/Beken WiFi MAC layer
    "bk_wifi_mac": [
        "rxu_",  # RX upper layer
        "txu_",  # TX upper layer
        "txl_",  # TX lower layer
        "rxl_",  # RX lower layer
        "scanu_",  # Scan unit
        "mm_hw_",  # MAC management hardware
        "mm_bcn",  # MAC management beacon
        "mm_tim",  # MAC management TIM
        "mm_check",  # MAC management checks
        "sm_connect",  # Station management
        "me_beacon",  # Management entity beacon
        "me_build",  # Management entity build
        "hapd_",  # Host AP daemon
        "chan_pre_",  # Channel management
        "handle_probe_",  # Probe handling
    ],
    # LibreTiny/Beken system control
    "bk_system": [
        "sctrl_",  # System control
        "icu_ctrl",  # Interrupt control unit
        "gdma_ctrl",  # DMA control
        "mpb_ctrl",  # MPB control
        "uf2_",  # UF2 OTA
        "bkreg_",  # Beken registers
    ],
    # LibreTiny/Beken BLE stack
    "bk_ble": [
        "gapc_",  # GAP client
        "gattc_",  # GATT client
        "attc_",  # ATT client
        "attmdb_",  # ATT database
        "atts_",  # ATT server
        "l2cc_",  # L2CAP
        "prf_env",  # Profile environment
    ],
    # LibreTiny/Beken scheduler
    "bk_scheduler": [
        "sch_plan_",  # Scheduler plan
        "sch_prog_",  # Scheduler program
        "sch_arb_",  # Scheduler arbiter
    ],
    # LibreTiny/Beken DMA descriptors
    "bk_dma": [
        "rx_payload_desc",
        "rx_dma_hdrdesc",
        "tx_hw_desc",
        "host_event_data",
        "host_cmd_data",
    ],
    # ARM EABI compiler runtime (LibreTiny uses ARM Cortex-M)
    "arm_runtime": [
        "__aeabi_",
        "__adddf3",
        "__subdf3",
        "__muldf3",
        "__divdf3",
        "__addsf3",
        "__subsf3",
        "__mulsf3",
        "__divsf3",
        "__gnu_unwind",
    ],
    "xtensa": ["xt_", "_xt_", "xPortEnterCriticalTimeout"],
    "heap": ["heap_", "multi_heap"],
    "spi_flash": ["spi_flash"],
    "rtc": ["rtc_", "rtcio_ll_"],
    "gpio_driver": ["gpio_", "pins"],
    "uart_driver": ["uart", "_uart", "UART"],
    "timer": ["timer_", "esp_timer"],
    "peripherals": ["periph_", "periman"],
    "network_stack": [
        "vj_compress",
        "raw_sendto",
        "raw_input",
        "etharp_",
        "icmp_input",
        "socket_ipv6",
        "ip_napt",
        "socket_ipv4_multicast",
        "socket_ipv6_multicast",
        "netconn_",
        "recv_raw",
        "accept_function",
        "netconn_recv_data",
        "netconn_accept",
        "netconn_write_vectors_partly",
        "netconn_drain",
        "raw_connect",
        "raw_bind",
        "icmp_send_response",
        "sockets",
        "icmp_dest_unreach",
        "inet_chksum_pseudo",
        "alloc_socket",
        "done_socket",
        "set_global_fd_sets",
        "inet_chksum_pbuf",
        "tryget_socket_unconn_locked",
        "tryget_socket_unconn",
        "cs_create_ctrl_sock",
        "netbuf_alloc",
        "tcp_",  # TCP protocol functions
        "udp_",  # UDP protocol functions
        "lwip_",  # LwIP stack functions
        "eagle_lwip",  # ESP-specific LwIP functions
        "new_linkoutput",  # Link output function
        "acd_",  # Address Conflict Detection (ACD)
        "eth_",  # Ethernet functions
        "mac_enable_bb",  # MAC baseband enable
        "reassemble_and_dispatch",  # Packet reassembly
    ],
    # dhcp must come before libc to avoid "dhcp_select" matching "select" pattern
    "dhcp": ["dhcp", "handle_dhcp"],
    "ipv6_stack": ["nd6_", "ip6_", "mld6_", "icmp6_", "icmp6_input"],
    # Order matters! More specific categories must come before general ones.
    # mdns must come before bluetooth to avoid "_mdns_disable_pcb" matching "ble_" pattern
    "mdns_lib": ["mdns", "packet$"],
    # memory_mgmt must come before wifi_stack to catch mmu_hal_* symbols
    "memory_mgmt": [
        "mem_",
        "memory_",
        "tlsf_",
        "memp_",
        "pbuf_",
        "pbuf_alloc",
        "pbuf_copy_partial_pbuf",
        "esp_mmu_map",
        "mmu_hal_",
        "s_do_mapping",  # Memory mapping function, not WiFi
        "hash_map_",  # Hash map data structure
        "umm_assimilate",  # UMM malloc assimilation
    ],
    # Bluetooth categories must come BEFORE wifi_stack to avoid misclassification
    # Many BLE symbols contain patterns like "ble_" that would otherwise match wifi patterns
    "bluetooth_rom": ["r_ble", "r_lld", "r_llc", "r_llm"],
    "bluedroid_bt": [
        "bluedroid",
        "btc_",
        "bta_",
        "btm_",
        "btu_",
        "BTM_",
        "GATT",
        "L2CA_",
        "smp_",
        "gatts_",
        "attp_",
        "l2cu_",
        "l2cb",
        "smp_cb",
        "BTA_GATTC_",
        "SMP_",
        "BTU_",
        "BTA_Dm",
        "GAP_Ble",
        "BT_tx_if",
        "host_recv_pkt_cb",
        "saved_local_oob_data",
        "string_to_bdaddr",
        "string_is_bdaddr",
        "CalConnectParamTimeout",
        "transmit_fragment",
        "transmit_data",
        "event_command_ready",
        "read_command_complete_header",
        "parse_read_local_extended_features_response",
        "parse_read_local_version_info_response",
        "should_request_high",
        "btdm_wakeup_request",
        "BTA_SetAttributeValue",
        "BTA_EnableBluetooth",
        "transmit_command_futured",
        "transmit_command",
        "get_waiting_command",
        "make_command",
        "transmit_downward",
        "host_recv_adv_packet",
        "copy_extra_byte_in_db",
        "parse_read_local_supported_commands_response",
    ],
    "bluetooth": [
        "bt_",
        "_ble_",  # More specific than "ble_" to avoid matching "able_", "enable_", "disable_"
        "l2c_",
        "l2ble_",  # L2CAP for BLE
        "gatt_",
        "gap_",
        "hci_",
        "btsnd_hcic_",  # Bluetooth HCI command send functions
        "BT_init",
        "BT_tx_",  # Bluetooth transmit functions
        "esp_ble_",  # Catch esp_ble_* functions
    ],
    "bluetooth_ll": [
        "llm_",  # Link layer manager
        "llc_",  # Link layer control
        "lld_",  # Link layer driver
        "ld_acl_",  # Link layer ACL (Asynchronous Connection-Oriented)
        "llcp_",  # Link layer control protocol
        "lmp_",  # Link manager protocol
    ],
    "wifi_bt_coex": ["coex"],
    "wifi_stack": [
        "ieee80211",
        "hostap",
        "sta_",
        "wifi_ap_",  # More specific than "ap_" to avoid matching "cap_", "map_"
        "wifi_scan_",  # More specific than "scan_" to avoid matching "_scan_" in other contexts
        "wifi_",
        "wpa_",
        "wps_",
        "esp_wifi",
        "cnx_",
        "wpa3_",
        "sae_",
        "wDev_",
        "ic_mac_",  # More specific than "mac_" to avoid matching emac_
        "esf_buf",
        "gWpaSm",
        "sm_WPA",
        "eapol_",
        "owe_",
        "wifiLowLevelInit",
        # Removed "s_do_mapping" - this is memory management, not WiFi
        "gScanStruct",
        "ppSearchTxframe",
        "ppMapWaitTxq",
        "ppFillAMPDUBar",
        "ppCheckTxConnTrafficIdle",
        "ppCalTkipMic",
        "phy_force_wifi",
        "phy_unforce_wifi",
        "write_wifi_chan",
        "wifi_track_pll",
    ],
    "crypto_math": [
        "ecp_",
        "bignum_",
        "mpi_",
        "sswu",
        "modp",
        "dragonfly_",
        "gcm_mult",
        "__multiply",
        "quorem",
        "__mdiff",
        "__lshift",
        "__mprec_tens",
        "ECC_",
        "multiprecision_",
        "mix_sub_columns",
        "sbox",
        "gfm2_sbox",
        "gfm3_sbox",
        "curve_p256",
        "curve",
        "p_256_init_curve",
        "shift_sub_rows",
        "rshift",
        "rijndaelEncrypt",  # AES Rijndael encryption
    ],
    # System and Arduino core functions must come before libc
    "esp_system": [
        "system_",  # ESP system functions
        "postmortem_",  # Postmortem reporting
    ],
    "arduino_core": [
        "pinMode",
        "millis",
        "micros",
        "delay(",  # More specific - Arduino delay function with parenthesis
        "delayMicroseconds",
        "digitalWrite",
        "digitalRead",
    ],
    "sntp": ["sntp_", "sntp_recv"],
    "scheduler": [
        "run_scheduled_",
        "compute_scheduled_",
        "event_TaskQueue",
    ],
    "hw_crypto": ["esp_aes", "esp_sha", "esp_rsa", "esp_bignum", "esp_mpi"],
    "libc": [
        "printf",
        "scanf",
        "malloc",
        "_free",  # More specific than "free" to match _free, __free_r, etc. but not arbitrary "free" substring
        "umm_free",  # UMM malloc free function
        "memcpy",
        "memset",
        "strcpy",
        "strlen",
        "_dtoa",
        "_fopen",
        "__sfvwrite_r",
        "qsort",
        "__sf",
        "__sflush_r",
        "__srefill_r",
        "_impure_data",
        "_reclaim_reent",
        "_open_r",
        "strncpy",
        "_strtod_l",
        "__gethex",
        "__hexnan",
        "_setenv_r",
        "_tzset_unlocked_r",
        "__tzcalc_limits",
        "_select",  # More specific than "select" to avoid matching "dhcp_select", etc.
        "scalbnf",
        "strtof",
        "strtof_l",
        "__d2b",
        "__b2d",
        "__s2b",
        "_Balloc",
        "__multadd",
        "__lo0bits",
        "__atexit0",
        "__smakebuf_r",
        "__swhatbuf_r",
        "_sungetc_r",
        "_close_r",
        "_link_r",
        "_unsetenv_r",
        "_rename_r",
        "__month_lengths",
        "tzinfo",
        "__ratio",
        "__hi0bits",
        "__ulp",
        "__any_on",
        "__copybits",
        "L_shift",
        "_fcntl_r",
        "_lseek_r",
        "_read_r",
        "_write_r",
        "_unlink_r",
        "_fstat_r",
        "access",
        "fsync",
        "tcsetattr",
        "tcgetattr",
        "tcflush",
        "tcdrain",
        "__ssrefill_r",
        "_stat_r",
        "__hexdig_fun",
        "__mcmp",
        "_fwalk_sglue",
        "__fpclassifyf",
        "_setlocale_r",
        "_mbrtowc_r",
        "fcntl",
        "__match",
        "_lock_close",
        "__c$",
        "__func__$",
        "__FUNCTION__$",
        "DAYS_IN_MONTH",
        "_DAYS_BEFORE_MONTH",
        # Note: CSWTCH$ symbols are GCC switch table lookup tables.
        # They are attributed to their source object files via _analyze_cswtch_symbols()
        # rather than being lumped into libc.
        "dst$",
        "sulp",
        "_strtol_l",  # String to long with locale
        "__cvt",  # Convert
        "__utoa",  # Unsigned to ASCII
        "__global_locale",  # Global locale
        "_ctype_",  # Character type
        "impure_data",  # Impure data
    ],
    "string_ops": [
        "strcmp",
        "strncmp",
        "strchr",
        "strstr",
        "strtok",
        "strdup",
        "strncasecmp_P",  # String compare (case insensitive, from program memory)
        "strnlen_P",  # String length (from program memory)
        "strncat_P",  # String concatenate (from program memory)
    ],
    "memory_alloc": ["malloc", "calloc", "realloc", "free", "_sbrk"],
    "file_io": [
        "fread",
        "fwrite",
        "fopen",
        "fclose",
        "fseek",
        "ftell",
        "fflush",
        "s_fd_table",
    ],
    "string_formatting": [
        "snprintf",
        "vsnprintf",
        "sprintf",
        "vsprintf",
        "sscanf",
        "vsscanf",
    ],
    "cpp_anonymous": ["_GLOBAL__N_", "n$"],
    # Plain C patterns only - C++ symbols will be categorized via DEMANGLED_PATTERNS
    "nvs": ["nvs_"],  # Plain C NVS functions
    "ota": ["ota_", "OTA", "esp_ota", "app_desc"],
    # cpp_runtime: Removed _ZN, _ZL to let DEMANGLED_PATTERNS categorize C++ symbols properly
    # Only keep patterns that are truly runtime-specific and not categorizable by namespace
    "cpp_runtime": ["__cxx", "_ZSt", "__gxx_personality", "_Z16"],
    "exception_handling": [
        "__cxa_",
        "_Unwind_",
        "__gcc_personality",
        "uw_frame_state",
        "search_object",  # Search for exception handling object
        "get_cie_encoding",  # Get CIE encoding
        "add_fdes",  # Add frame description entries
        "fde_unencoded_compare",  # Compare FDEs
        "fde_mixed_encoding_compare",  # Compare mixed encoding FDEs
        "frame_downheap",  # Frame heap operations
        "frame_heapsort",  # Frame heap sorting
    ],
    "static_init": ["_GLOBAL__sub_I_"],
    "phy_radio": [
        "phy_",
        "rf_",
        "chip_",
        "register_chipv7",
        "pbus_",
        "bb_",
        "fe_",
        "rfcal_",
        "ram_rfcal",
        "tx_pwctrl",
        "rx_chan",
        "set_rx_gain",
        "set_chan",
        "agc_reg",
        "ram_txiq",
        "ram_txdc",
        "ram_gen_rx_gain",
        "rx_11b_opt",
        "set_rx_sense",
        "set_rx_gain_cal",
        "set_chan_dig_gain",
        "tx_pwctrl_init_cal",
        "rfcal_txiq",
        "set_tx_gain_table",
        "correct_rfpll_offset",
        "pll_correct_dcap",
        "txiq_cal_init",
        "pwdet_sar",
        "pwdet_sar2_init",
        "ram_iq_est_enable",
        "ram_rfpll_set_freq",
        "ant_wifirx_cfg",
        "ant_btrx_cfg",
        "force_txrxoff",
        "force_txrx_off",
        "tx_paon_set",
        "opt_11b_resart",
        "rfpll_1p2_opt",
        "ram_dc_iq_est",
        "ram_start_tx_tone",
        "ram_en_pwdet",
        "ram_cbw2040_cfg",
        "rxdc_est_min",
        "i2cmst_reg_init",
        "temprature_sens_read",
        "ram_restart_cal",
        "ram_write_gain_mem",
        "ram_wait_rfpll_cal_end",
        "txcal_debuge_mode",
        "ant_wifitx_cfg",
        "reg_init_begin",
        "tx_cap_init",  # TX capacitance init
        "ram_set_txcap",  # RAM TX capacitance setting
        "tx_atten_",  # TX attenuation
        "txiq_",  # TX I/Q calibration
        "ram_cal_",  # RAM calibration
        "ram_rxiq_",  # RAM RX I/Q
        "readvdd33",  # Read VDD33
        "test_tout",  # Test timeout
        "tsen_meas",  # Temperature sensor measurement
        "bbpll_cal",  # Baseband PLL calibration
        "set_cal_",  # Set calibration
        "set_rfanagain_",  # Set RF analog gain
        "set_txdc_",  # Set TX DC
        "get_vdd33_",  # Get VDD33
        "gen_rx_gain_table",  # Generate RX gain table
        "ram_ana_inf_gating_en",  # RAM analog interface gating enable
        "tx_cont_en",  # TX continuous enable
        "tx_delay_cfg",  # TX delay configuration
        "tx_gain_table_set",  # TX gain table set
        "check_and_reset_hw_deadlock",  # Hardware deadlock check
        "s_config",  # System/hardware config
        "chan14_mic_cfg",  # Channel 14 MIC config
    ],
    "wifi_phy_pp": [
        "pp_",
        "ppT",
        "ppR",
        "ppP",
        "ppInstall",
        "ppCalTxAMPDULength",
        "ppCheckTx",  # Packet processor TX check
        "ppCal",  # Packet processor calibration
        "HdlAllBuffedEb",  # Handle buffered EB
    ],
    "wifi_lmac": ["lmac"],
    "wifi_device": [
        "wdev",
        "wDev_",
        "ic_set_sta",  # Set station mode
        "ic_set_vif",  # Set virtual interface
    ],
    "power_mgmt": [
        "pm_",
        "sleep",
        "rtc_sleep",
        "light_sleep",
        "deep_sleep",
        "power_down",
        "g_pm",
        "pmc",  # Power Management Controller
    ],
    "hal_layer": ["hal_"],
    "clock_mgmt": [
        "clk_",
        "clock_",
        "rtc_clk",
        "apb_",
        "cpu_freq",
        "setCpuFrequencyMhz",
    ],
    "cache_mgmt": ["cache"],
    "flash_ops": ["flash", "image_load"],
    "interrupt_handlers": [
        "isr",
        "interrupt",
        "intr_",
        "exc_",
        "exception",
        "port_IntStack",
    ],
    "wrapper_functions": ["_wrapper"],
    "error_handling": ["panic", "abort", "assert", "error_", "fault"],
    "authentication": ["auth"],
    "ppp_protocol": ["ppp", "ipcp_", "lcp_", "chap_", "LcpEchoCheck"],
    "ethernet_phy": [
        "emac_",
        "eth_phy_",
        "phy_tlk110",
        "phy_lan87",
        "phy_ip101",
        "phy_rtl",
        "phy_dp83",
        "phy_ksz",
        "lan87xx_",
        "rtl8201_",
        "ip101_",
        "ksz80xx_",
        "jl1101_",
        "dp83848_",
        "eth_on_state_changed",
    ],
    "threading": ["pthread_", "thread_", "_task_"],
    "pthread": ["pthread"],
    "synchronization": ["mutex", "semaphore", "spinlock", "portMUX"],
    "math_lib": [
        "sin",
        "cos",
        "tan",
        "sqrt",
        "pow",
        "exp",
        "log",
        "atan",
        "asin",
        "acos",
        "floor",
        "ceil",
        "fabs",
        "round",
    ],
    "random": ["rand", "random", "rng_", "prng"],
    "time_lib": [
        "time",
        "clock",
        "gettimeofday",
        "settimeofday",
        "localtime",
        "gmtime",
        "mktime",
        "strftime",
    ],
    "console_io": ["console_", "uart_tx", "uart_rx", "puts", "putchar", "getchar"],
    "rom_functions": ["r_", "rom_"],
    "compiler_runtime": [
        "__divdi3",
        "__udivdi3",
        "__moddi3",
        "__muldi3",
        "__ashldi3",
        "__ashrdi3",
        "__lshrdi3",
        "__cmpdi2",
        "__fixdfdi",
        "__floatdidf",
    ],
    "libgcc": ["libgcc", "_divdi3", "_udivdi3"],
    "boot_startup": ["boot", "start_cpu", "call_start", "startup", "bootloader"],
    "bootloader": ["bootloader_", "esp_bootloader"],
    "app_framework": ["app_", "initArduino", "setup", "loop", "Update"],
    "weak_symbols": ["__weak_"],
    "compiler_builtins": ["__builtin_"],
    "vfs": ["vfs_", "VFS"],
    "esp32_sdk": ["esp32_", "esp32c", "esp32s"],
    "usb": ["usb_", "USB", "cdc_", "CDC"],
    "i2c_driver": ["i2c_", "I2C"],
    "i2s_driver": ["i2s_", "I2S"],
    "spi_driver": ["spi_", "SPI"],
    "adc_driver": ["adc_", "ADC"],
    "dac_driver": ["dac_", "DAC"],
    "touch_driver": ["touch_", "TOUCH"],
    "pwm_driver": ["pwm_", "PWM", "ledc_", "LEDC"],
    "rmt_driver": ["rmt_", "RMT"],
    "pcnt_driver": ["pcnt_", "PCNT"],
    "can_driver": ["can_", "CAN", "twai_", "TWAI"],
    "sdmmc_driver": ["sdmmc_", "SDMMC", "sdcard", "sd_card"],
    "temp_sensor": ["temp_sensor", "tsens_"],
    "watchdog": ["wdt_", "WDT", "watchdog"],
    "brownout": ["brownout", "bod_"],
    "ulp": ["ulp_", "ULP"],
    "psram": ["psram", "PSRAM", "spiram", "SPIRAM"],
    "efuse": ["efuse", "EFUSE"],
    "partition": ["partition", "esp_partition"],
    "esp_event": ["esp_event", "event_loop", "event_callback"],
    "esp_console": ["esp_console", "console_"],
    "chip_specific": ["chip_", "esp_chip"],
    "esp_system_utils": ["esp_system", "esp_hw", "esp_clk", "esp_sleep"],
    "ipc": ["esp_ipc", "ipc_"],
    "wifi_config": [
        "g_cnxMgr",
        "gChmCxt",
        "g_ic",
        "TxRxCxt",
        "s_dp",
        "s_ni",
        "s_reg_dump",
        "d_mult_table",
        "K",
        "fcstab",
    ],
    "smartconfig": ["sc_ack_send"],
    "rc_calibration": ["rc_cal", "rcUpdate"],
    "noise_floor": ["noise_check"],
    "rf_calibration": [
        "set_rx_sense",
        "set_rx_gain_cal",
        "set_chan_dig_gain",
        "tx_pwctrl_init_cal",
        "rfcal_txiq",
        "set_tx_gain_table",
        "correct_rfpll_offset",
        "pll_correct_dcap",
        "txiq_cal_init",
        "pwdet_sar",
        "rx_11b_opt",
    ],
    "wifi_crypto": [
        "pk_use_ecparams",
        "process_segments",
        "ccmp_",
        "rc4_",
        "aria_",
        "mgf_mask",
        "dh_group",
        "ccmp_aad_nonce",
        "ccmp_encrypt",
        "rc4_skip",
        "aria_sb1",
        "aria_sb2",
        "aria_is1",
        "aria_is2",
        "aria_sl",
        "aria_a",
    ],
    "radio_control": ["fsm_input", "fsm_sconfreq"],
    "pbuf": [
        "pbuf_",
    ],
    "event_group": ["xEventGroup"],
    "ringbuffer": ["xRingbuffer", "prvSend", "prvReceive", "prvCopy"],
    "provisioning": ["prov_", "prov_stop_and_notify"],
    "scan": ["gScanStruct"],
    "port": ["xPort"],
    "elf_loader": [
        "elf_add",
        "elf_add_note",
        "elf_add_segment",
        "process_image",
        "read_encoded",
        "read_encoded_value",
        "read_encoded_value_with_base",
        "process_image_header",
    ],
    "socket_api": [
        "sockets",
        "netconn_",
        "accept_function",
        "recv_raw",
        "socket_ipv4_multicast",
        "socket_ipv6_multicast",
    ],
    "igmp": ["igmp_", "igmp_send", "igmp_input"],
    "icmp6": ["icmp6_"],
    "arp": ["arp_table"],
    "ampdu": [
        "ampdu_",
        "rcAmpdu",
        "trc_onAmpduOp",
        "rcAmpduLowerRate",
        "ampdu_dispatch_upto",
    ],
    "ieee802_11": ["ieee802_11_", "ieee802_11_parse_elems"],
    "rate_control": [
        "rssi_margin",
        "rcGetSched",
        "get_rate_fcc_index",
        "rcGetRate",  # Get rate
        "rc_get_",  # Rate control getters
        "rc_set_",  # Rate control setters
        "rc_enable_",  # Rate control enable functions
    ],
    "nan": ["nan_dp_", "nan_dp_post_tx", "nan_dp_delete_peer"],
    "channel_mgmt": ["chm_init", "chm_set_current_channel"],
    "trace": ["trc_init", "trc_onAmpduOp"],
    "country_code": ["country_info", "country_info_24ghz"],
    "multicore": ["do_multicore_settings"],
    "Update_lib": ["Update"],
    "stdio": [
        "__sf",
        "__sflush_r",
        "__srefill_r",
        "_impure_data",
        "_reclaim_reent",
        "_open_r",
    ],
    "strncpy_ops": ["strncpy"],
    "math_internal": ["__mdiff", "__lshift", "__mprec_tens", "quorem"],
    "character_class": ["__chclass"],
    "camellia": ["camellia_", "camellia_feistel"],
    "crypto_tables": [
        "FSb",
        "FSb2",
        "FSb3",
        "FSb4",
        "Te0",  # AES encryption table
        "Td0",  # AES decryption table
        "crc32_table",  # CRC32 lookup table
        "crc_tab",  # CRC lookup table
    ],
    "crypto_hash": [
        "SHA1Transform",  # SHA1 hash function
        "MD5Transform",  # MD5 hash function
        "SHA256",
        "SHA512",
    ],
    "event_buffer": ["g_eb_list_desc", "eb_space"],
    "base_node": ["base_node_", "base_node_add_handler"],
    "file_descriptor": ["s_fd_table"],
    "tx_delay": ["tx_delay_cfg"],
    "deinit": ["deinit_functions"],
    "lcp_echo": ["LcpEchoCheck"],
    "raw_api": ["raw_bind", "raw_connect"],
    "checksum": ["process_checksum"],
    "entry_management": ["add_entry"],
    "esp_ota": ["esp_ota", "ota_", "read_otadata"],
    "http_server": [
        "httpd_",
        "parse_url_char",
        "cb_headers_complete",
        "delete_entry",
        "validate_structure",
        "config_save",
        "config_new",
        "verify_url",
        "cb_url",
    ],
    "misc_system": [
        "alarm_cbs",
        "start_up",
        "tokens",
        "unhex",
        "osi_funcs_ro",
        "enum_function",
        "fragment_and_dispatch",
        "alarm_set",
        "osi_alarm_new",
        "config_set_string",
        "config_update_newest_section",
        "config_remove_key",
        "method_strings",
        "interop_match",
        "interop_database",
        "__state_table",
        "__action_table",
        "s_stub_table",
        "s_context",
        "s_mmu_ctx",
        "s_get_bus_mask",
        "hli_queue_put",
        "list_remove",
        "list_delete",
        "lock_acquire_generic",
        "is_vect_desc_usable",
        "io_mode_str",
        "__c$20233",
        "interface",
        "read_id_core",
        "subscribe_idle",
        "unsubscribe_idle",
        "s_clkout_handle",
        "lock_release_generic",
        "config_set_int",
        "config_get_int",
        "config_get_string",
        "config_has_key",
        "config_remove_section",
        "osi_alarm_init",
        "osi_alarm_deinit",
        "fixed_queue_enqueue",
        "fixed_queue_dequeue",
        "fixed_queue_new",
        "fixed_pkt_queue_enqueue",
        "fixed_pkt_queue_new",
        "list_append",
        "list_prepend",
        "list_insert_after",
        "list_contains",
        "list_get_node",
        "hash_function_blob",
        "cb_no_body",
        "cb_on_body",
        "profile_tab",
        "get_arg",
        "trim",
        "buf$",
        "process_appended_hash_and_sig$constprop$0",
        "uuidType",
        "allocate_svc_db_buf",
        "_hostname_is_ours",
        "s_hli_handlers",
        "tick_cb",
        "idle_cb",
        "input",
        "entry_find",
        "section_find",
        "find_bucket_entry_",
        "config_has_section",
        "hli_queue_create",
        "hli_queue_get",
        "hli_c_handler",
        "future_ready",
        "future_await",
        "future_new",
        "pkt_queue_enqueue",
        "pkt_queue_dequeue",
        "pkt_queue_cleanup",
        "pkt_queue_create",
        "pkt_queue_destroy",
        "fixed_pkt_queue_dequeue",
        "osi_alarm_cancel",
        "osi_alarm_is_active",
        "osi_sem_take",
        "osi_event_create",
        "osi_event_bind",
        "alarm_cb_handler",
        "list_foreach",
        "list_back",
        "list_front",
        "list_clear",
        "fixed_queue_try_peek_first",
        "translate_path",
        "get_idx",
        "find_key",
        "init",
        "end",
        "start",
        "set_read_value",
        "copy_address_list",
        "copy_and_key",
        "sdk_cfg_opts",
        "leftshift_onebit",
        "config_section_end",
        "config_section_begin",
        "find_entry_and_check_all_reset",
        "image_validate",
        "xPendingReadyList",
        "vListInitialise",
        "lock_init_generic",
        "ant_bttx_cfg",
        "ant_dft_cfg",
        "cs_send_to_ctrl_sock",
        "config_llc_util_funcs_reset",
        "make_set_adv_report_flow_control",
        "make_set_event_mask",
        "raw_new",
        "raw_remove",
        "BTE_InitStack",
        "parse_read_local_supported_features_response",
        "__math_invalidf",
        "tinytens",
        "__mprec_tinytens",
        "__mprec_bigtens",
        "vRingbufferDelete",
        "vRingbufferDeleteWithCaps",
        "vRingbufferReturnItem",
        "vRingbufferReturnItemFromISR",
        "get_acl_data_size_ble",
        "get_features_ble",
        "get_features_classic",
        "get_acl_packet_size_ble",
        "get_acl_packet_size_classic",
        "supports_extended_inquiry_response",
        "supports_rssi_with_inquiry_results",
        "supports_interlaced_inquiry_scan",
        "supports_reading_remote_extended_features",
    ],
}

# Demangled patterns: patterns found in demangled C++ names
DEMANGLED_PATTERNS = {
    "gpio_driver": ["GPIO"],
    "uart_driver": ["UART"],
    # mdns_lib must come before network_stack to avoid "udp" matching "_udpReadBuffer" in MDNSResponder
    "mdns_lib": [
        "MDNSResponder",
        "MDNSImplementation",
        "MDNS",
    ],
    "network_stack": [
        "lwip",
        "tcp",
        "udp",
        "ip4",
        "ip6",
        "dhcp",
        "dns",
        "netif",
        "ethernet",
        "ppp",
        "slip",
        "UdpContext",  # UDP context class
        "DhcpServer",  # DHCP server class
    ],
    "arduino_core": [
        "String::",  # Arduino String class
        "Print::",  # Arduino Print class
        "HardwareSerial::",  # Serial class
        "IPAddress::",  # IP address class
        "EspClass::",  # ESP class
        "experimental::_SPI",  # Experimental SPI
    ],
    "ota": [
        "UpdaterClass",
        "Updater::",
    ],
    "wifi": [
        "ESP8266WiFi",
        "WiFi::",
    ],
    "wifi_stack": ["NetworkInterface"],
    "nimble_bt": [
        "nimble",
        "NimBLE",
        "ble_hs",
        "ble_gap",
        "ble_gatt",
        "ble_att",
        "ble_l2cap",
        "ble_sm",
    ],
    "crypto": ["mbedtls", "crypto", "sha", "aes", "rsa", "ecc", "tls", "ssl"],
    "cpp_stdlib": ["std::", "__gnu_cxx::", "__cxxabiv"],
    "static_init": ["__static_initialization"],
    "rtti": ["__type_info", "__class_type_info"],
    "web_server_lib": ["AsyncWebServer", "AsyncWebHandler", "WebServer"],
    "async_tcp": ["AsyncClient", "AsyncServer"],
    "json_lib": [
        "ArduinoJson",
        "JsonDocument",
        "JsonArray",
        "JsonObject",
        "deserialize",
        "serialize",
    ],
    "http_lib": ["HTTP", "http_", "Request", "Response", "Uri", "WebSocket"],
    "logging": ["log", "Log", "print", "Print", "diag_"],
    "authentication": ["checkDigestAuthentication"],
    "libgcc": ["libgcc"],
    "esp_system": ["esp_", "ESP"],
    "arduino": ["arduino"],
    "nvs": ["nvs_", "_ZTVN3nvs", "nvs::"],
    "filesystem": ["spiffs", "vfs"],
    "libc": ["newlib"],
}

# Patterns for categorizing ESPHome core symbols into subcategories
CORE_SUBCATEGORY_PATTERNS = {
    "Component Framework": ["Component"],
    "Application Core": ["Application"],
    "Scheduler": ["Scheduler"],
    "Component Iterator": ["ComponentIterator"],
    "Helper Functions": ["Helpers", "helpers"],
    "Preferences/Storage": ["Preferences", "ESPPreferences"],
    "I/O Utilities": ["HighFrequencyLoopRequester"],
    "String Utilities": ["str_"],
    "Bit Utilities": ["reverse_bits"],
    "Data Conversion": ["convert_"],
    "Network Utilities": ["network", "IPAddress"],
    "API Protocol": ["api::"],
    "WiFi Manager": ["wifi::"],
    "MQTT Client": ["mqtt::"],
    "Logger": ["logger::"],
    "OTA Updates": ["ota::"],
    "Web Server": ["web_server::"],
    "Time Management": ["time::"],
    "Sensor Framework": ["sensor::"],
    "Binary Sensor": ["binary_sensor::"],
    "Switch Framework": ["switch_::"],
    "Light Framework": ["light::"],
    "Climate Framework": ["climate::"],
    "Cover Framework": ["cover::"],
}
