Xiaofen Xing

148 papers A* 4A 13B 8C 1Misc 11Journal 77Unranked 34
YearRankTypeTitle / Venue / Authors
2026 J jnl
Expert Syst. Appl.
Wenfeng Jiang, Ziyi Zhao, Lin Wang, Fang Liu, Chunmei Qing, Xiaofen Xing, Xiangmin Xu, Weiquan Fan, Zhanpeng Jin
2026 J jnl
CoRR
Xiangyu Li, Xuan Yao, Guohao Qi, Fengbin Zhu, Kelvin J. L. Koa, Xiang Yao Ng, Ziyang Liu, Xingyu Ni, Chang Liu, Yonghui Yang, Yang Zhang, Wenjie Wang, Fuli Feng, Chao Wang, Huanbo Luan, Xiaofen Xing, Xiangmin Xu, Tat-Seng Chua, Ke-Wei Huang
2026 J jnl
CoRR
Zhenyu Wang, Xiaofen Xing, Yirong Chen, Xiangmin Xu
2026 J jnl
Knowl. Based Syst.
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2026 J jnl
Neurocomputing
Huachao Yan, Kailing Guo, Shiwei Song, Xiaofen Xing, Xiangmin Xu
2026 J jnl
IEEE Trans. Vis. Comput. Graph.
Zikai Huang, Yihan Zhou, Xuemiao Xu, Cheng Xu, Xiaofen Xing, Jing Qin, Shengfeng He
2025 A conf
INTERSPEECH
Jialong Mai, Xiaofen Xing, Weidong Chen, Yuanbo Fang, Xiangmin Xu
2025 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Zhaojie Chu, Kailing Guo, Xiaofen Xing, Bolun Cai, Shan He, Xiangmin Xu
2025 J jnl
CoRR
Jingyuan Xing, Mingru Yang, Zhipeng Li, Xiaofen Xing, Xiangmin Xu
2025 conf
EMNLP (Findings)
Mingyu Chen, Jingkai Lin, Zhaojie Chu, Xiaofen Xing, Yirong Chen, Xiangmin Xu
2025 J jnl
CoRR
Mingyu Chen, Jingkai Lin, Zhaojie Chu, Xiaofen Xing, Yirong Chen, Xiangmin Xu
2025 J jnl
IEEE Trans. Ind. Informatics
Tianlei Wang, Zeliang Li, Ying Xu, Yikui Zhai, Xiaofen Xing, Kailing Guo, Pasquale Coscia, Angelo Genovese, Vincenzo Piuri, Fabio Scotti
2025 J jnl
IEEE Trans. Affect. Comput.
Shaoping Jiang, Xiaofen Xing, Fang Liu, Xiangmin Xu, Lin Wang, Kailing Guo
2025 A conf
INTERSPEECH
Jialong Mai, Xiaofen Xing, Yangbiao Li, Xiangmin Xu
2025 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Kailing Guo, Zhenquan Lin, Canyang Chen, Xiaofen Xing, Fang Liu, Xiangmin Xu
2025 J jnl
Speech Commun.
Weiquan Fan, Xiangmin Xu, Guohua Zhou, Xiaofang Deng, Xiaofen Xing
2025 J jnl
IEEE Trans. Multim.
Zhaojie Chu, Kailing Guo, Xiaofen Xing, Pengsheng Liu, Bolun Cai, Xiangmin Xu
2025 Misc conf
ICASSP
Jingyuan Xing, Shuaiqi Chen, Xiangmin Xu, Xiaofen Xing
2025 J jnl
CoRR
Jialong Mai, Xiaofen Xing, Yawei Li, Zhipeng Li, Jingyuan Xing, Xiangmin Xu
2025 A conf
INTERSPEECH
Jingyuan Xing, Zhipeng Li, Shuaiqi Chen, Xiaofen Xing, Xiangmin Xu
2025 A* conf
IJCAI
Yufeng Wang, Jinwu Hu, Ziteng Huang, Kunyang Lin, Zitian Zhang, Peihao Chen, Yu Hu, Qianyue Wang, Zhuliang Yu, Bin Sun, Xiaofen Xing, Qingfang Zheng, Mingkui Tan
2025 J jnl
CoRR
Yufeng Wang, Jinwu Hu, Ziteng Huang, Kunyang Lin, Zitian Zhang, Peihao Chen, Yu Hu, Qianyue Wang, Zhuliang Yu, Bin Sun, Xiaofen Xing, Qingfang Zheng, Mingkui Tan
2025 conf
ICCVW
Sijin Yu, Zijiao Chen, Wenxuan Wu, Shengxian Chen, Zhongliang Liu, Jingxin Nie, Xiaofen Xing, Xiangmin Xu, Xin Zhang
2025 J jnl
CoRR
Sijin Yu, Zijiao Chen, Wenxuan Wu, Shengxian Chen, Zhongliang Liu, Jingxin Nie, Xiaofen Xing, Xiangmin Xu, Xin Zhang
2025 J jnl
CoRR
Sihang Nie, Xiaofen Xing, Jingyuan Xing, Baiji Liu, Xiangmin Xu
2025 conf
WWW (Companion Volume)
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2025 J jnl
CoRR
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2025 conf
MICCAI (12)
Jiakun Xu, Xin Zhang, Tong Xiong, Shengxian Chen, Xiaofen Xing, Jindou Hao, Xiangmin Xu
2025 J jnl
IEEE Trans. Affect. Comput.
Yuanbo Fang, Xiaofen Xing, Zhaojie Chu, Yifeng Du, Xiangmin Xu
2025 C conf
ASRU
Yangbiao Li, Xiaofen Xing, Jialong Mai, Jingyuan Xing, Xiangmin Xu
2025 A conf
INTERSPEECH
Zhipeng Li, Xiaofen Xing, Jingyuan Xing, Hangrui Hu, Heng Lu, Xiangmin Xu
2025 J jnl
CoRR
Zhipeng Li, Xiaofen Xing, Jingyuan Xing, Hangrui Hu, Heng Lu, Xiangmin Xu
2025 J jnl
Expert Syst. Appl.
Yanxiong Li, Qisheng Huang, Xiaofen Xing, Xiangmin Xu
2025 Misc conf
ICASSP
Rui Liu, Xiaofen Xing, Zheng Lian, Haizhou Li, Björn W. Schuller, Haolin Zuo
2025 A conf
INTERSPEECH
Yuanbo Fang, Xiaofen Xing, Xueru Li, Weibin Zhang, Xiangmin Xu
2025 J jnl
CoRR
Jialong Mai, Jinxin Ji, Xiaofen Xing, Chen Yang, Weidong Chen, Jingyuan Xing, Xiangmin Xu
2025 J jnl
CoRR
Lianlian Liu, YongKang He, Zhaojie Chu, Xiaofen Xing, Xiangmin Xu
2025 J jnl
Expert Syst. Appl.
Weiquan Fan, Xiangmin Xu, Fang Liu, Xiaofen Xing
2025 J jnl
CoRR
Jingyuan Xing, Zhipeng Li, Jialong Mai, Xiaofen Xing, Xiangmin Xu
2025 J jnl
CoRR
Yongyi Su, Haojie Zhang, Shijie Li, Nanqing Liu, Jingyi Liao, Junyi Pan, Yuan Liu, Xiaofen Xing, Chong Sun, Chen Li, Nancy F. Chen, Shuicheng Yan, XuLei Yang, Xun Xu
2025 J jnl
CoRR
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2025 conf
ACL (1)
Haojie Xie, Yirong Chen, Xiaofen Xing, Jingkai Lin, Xiangmin Xu
2025 conf
EMNLP (Findings)
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2025 J jnl
CoRR
Xiangyu Li, Yawen Zeng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2025 J jnl
CoRR
Yuanbo Fang, Haoze Sun, Jun Liu, Tao Zhang, Zenan Zhou, Weipeng Chen, Xiaofen Xing, Xiangmin Xu
2025 A conf
INTERSPEECH
Xueru Li, Jingyuan Xing, Xiaofen Xing, Zhipeng Li, Xiangmin Xu
2025 A* conf
EMNLP
Wenyu Tao, Xiaofen Xing, Zeliang Li, Xiangmin Xu
2025 conf
ISBI
Zhaojin Chen, Sijin Yu, Xuejiao Li, Huirong Lei, Jiyu Qian, Yingxue Yao, Zicong Zheng, Guodong Liang, Xiaofen Xing, Xin Zhang, Chengfang Xu
2025 A* conf
ACM Multimedia
Pengsheng Liu, Zhaojie Chu, Xiaofen Xing, Xiangmin Xu
2025 Misc conf
ICASSP
Rongjin Li, Weibin Zhang, Dongpeng Chen, Jintao Kang, Xiaofen Xing
2025 J jnl
CoRR
Rongjin Li, Weibin Zhang, Dongpeng Chen, Jintao Kang, Xiaofen Xing
2025 conf
EMNLP (Findings)
Zhenpeng Gao, Xiaofen Xing, Xiangmin Xu
2025 J jnl
CoRR
Zikai Huang, Yihan Zhou, Xuemiao Xu, Cheng Xu, Xiaofen Xing, Jing Qin, Shengfeng He
2025 J jnl
Neural Networks
Weiying Xue, Qi Liu, Yuxiao Wang, Zhenao Wei, Xiaofen Xing, Xiangmin Xu
2025 conf
ACL (Findings)
Wenyu Tao, Xiaofen Xing, Yirong Chen, Linyi Huang, Xiangmin Xu
2025 J jnl
Knowl. Based Syst.
Ziyi Zhao, Kailing Guo, Fang Liu, Xiaofen Xing, Lin Wang, Xiangmin Xu, Zhanpeng Jin
2024 conf
SLT
Zhipeng Li, Xiaofen Xing, Jun Wang, Shuaiqi Chen, Guoqiao Yu, Guanglu Wan, Xiangmin Xu
2024 conf
PRIME@MICCAI
Sijin Yu, Xuejiao Li, Huirong Lei, Yingxue Yao, Zhaojin Chen, Zicong Zheng, Guodong Liang, Xiaofen Xing, Xin Zhang, Chengfang Xu
2024 J jnl
IEEE Trans. Affect. Comput.
Huachao Yan, Kailing Guo, Xiaofen Xing, Xiangmin Xu
2024 Misc conf
ICASSP
Han Chen, Wenxuan Wu, Xiaofen Xing, Xiangmin Xu
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Zhaojie Chu, Kailing Guo, Xiaofen Xing, Yilin Lan, Bolun Cai, Xiangmin Xu
2024 conf
MICCAI (2)
Wenxuan Wu, Ruowen Qu, Dongzi Shi, Tong Xiong, Xiangmin Xu, Xiaofen Xing, Xin Zhang
2024 conf
MLMI@MICCAI (1)
Wenxuan Wu, Tong Xiong, Dongzi Shi, Ruowen Qu, Xiangmin Xu, Xiaofen Xing, Xin Zhang
2024 conf
SLT
Huadong Lin, Yirong Chen, Wenyu Tao, Mingyu Chen, Xiangmin Xu, Xiaofen Xing
2024 A conf
INTERSPEECH
Jialong Mai, Xiaofen Xing, Weidong Chen, Xiangmin Xu
2024 J jnl
CoRR
Rui Liu, Haolin Zuo, Zheng Lian, Xiaofen Xing, Björn W. Schuller, Haizhou Li
2024 conf
WWW (Companion Volume)
Xiangyu Li, Xinjie Shen, Yawen Zeng, Xiaofen Xing, Jin Xu
2024 J jnl
CoRR
Xiangyu Li, Xinjie Shen, Yawen Zeng, Xiaofen Xing, Jin Xu
2024 conf
ICIC (13)
Kai Zhang, Linping Gao, Jinda Lu, Yutong Yuan, Xiaofen Xing
2024 J jnl
CoRR
Baozhu Zhao, Qiwei Xiong, Xiaohan Zhang, Jingfeng Guo, Qi Liu, Xiaofen Xing, Xiangmin Xu
2024 J jnl
CoRR
Haojie Xie, Yirong Chen, Xiaofen Xing, Jingkai Lin, Xiangmin Xu
2024 conf
ICIC (13)
Kai Zhang, Linping Gao, Zhaobao Yang, Biao Zhang, Xiaofen Xing
2024 B conf
ICMR
Yan Wang, Yawen Zeng, Junjie Liang, Xiaofen Xing, Jin Xu, Xiangmin Xu
2024 J jnl
CoRR
Huachao Yan, Kailing Guo, Shiwei Song, Yihai Dai, Xiaoqiang Wei, Xiaofen Xing, Xiangmin Xu
2024 J jnl
Frontiers Inf. Technol. Electron. Eng.
Weining Wang, Jiahui Li, Yifan Li, Xiaofen Xing
2024 J jnl
CoRR
Weiying Xue, Qi Liu, Qiwei Xiong, Yuxiao Wang, Zhenao Wei, Xiaofen Xing, Xiangmin Xu
2024 J jnl
IEEE Trans. Affect. Comput.
Weidong Chen, Xiaofen Xing, Peihao Chen, Xiangmin Xu
2024 J jnl
CoRR
Yan Wang, Yawen Zeng, Jingsheng Zheng, Xiaofen Xing, Jin Xu, Xiangmin Xu
2023 conf
ISBI
Jing Liang, Yingxue Yao, Xin Zhang, Jieling Wu, Xiaofen Xing
2023 J jnl
CoRR
Yirong Chen, Zhenyu Wang, Xiaofen Xing, Huimin Zheng, Zhipei Xu, Kai Fang, Junhong Wang, Sihang Li, Jieling Wu, Qi Liu, Xiangmin Xu
2023 J jnl
CoRR
Zhaojie Chu, Kailing Guo, Xiaofen Xing, Yilin Lan, Bolun Cai, Xiangmin Xu
2023 B conf
IJCNN
Yicai Yang, Xiaofen Xing, Ming Chen, Kailing Guo, Xiangmin Xu, Fang Liu
2023 Misc conf
ICASSP
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2023 J jnl
CoRR
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2023 Misc conf
ICASSP
Shuaiqi Chen, Xiaofen Xing, Weibin Zhang, Weidong Chen, Xiangmin Xu
2023 J jnl
CoRR
Shuaiqi Chen, Xiaofen Xing, Weibin Zhang, Weidong Chen, Xiangmin Xu
2023 A conf
INTERSPEECH
Yuanbo Fang, Xiaofen Xing, Xiangmin Xu, Weibin Zhang
2023 conf
SNPD-Winter
Wenying Lu, Xin Zhang, Qin Xu, Wenjun Chen, Chaoxiang Yang, Xiaofen Xing, Xiangmin Xu
2023 J jnl
CoRR
Pucheng Zhai, Kailing Guo, Fang Liu, Xiaofen Xing, Xiangmin Xu
2023 Misc conf
ICASSP
Weiquan Fan, Xiaofen Xing, Bolun Cai, Xiangmin Xu
2023 A conf
INTERSPEECH
Zhipeng Li, Xiaofen Xing, Yuanbo Fang, Weibin Zhang, Hengsheng Fan, Xiangmin Xu
2023 conf
EMNLP (Findings)
Yirong Chen, Xiaofen Xing, Jingkai Lin, Huimin Zheng, Zhenyu Wang, Qi Liu, Xiangmin Xu
2023 J jnl
CoRR
Yirong Chen, Xiaofen Xing, Jingkai Lin, Huimin Zheng, Zhenyu Wang, Qi Liu, Xiangmin Xu
2023 Misc conf
ICASSP
Wenjing Han, Yirong Chen, Xiaofen Xing, Guohua Zhou, Xiangmin Xu
2023 J jnl
CoRR
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2023 J jnl
IEEE ACM Trans. Audio Speech Lang. Process.
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2023 J jnl
CoRR
Weidong Chen, Xiaofen Xing, Peihao Chen, Xiangmin Xu
2022 J jnl
IEEE Trans. Cogn. Dev. Syst.
Ting Lu, Zhengfu Peng, Xiaofen Xing, Xiangmin Xu, Jianxin Pang
2022 J jnl
Digit. Signal Process.
Chunmei Qing, Huansheng Zhu, Xiaofen Xing, Dongwen Chen, Jianxiu Jin
2022 J jnl
CoRR
Yirong Chen, Weiquan Fan, Xiaofen Xing, Jianxin Pang, Minlie Huang, Wenjing Han, Qianfeng Tie, Xiangmin Xu
2022 Misc conf
ICASSP
Shaoping Jiang, Xiangmin Xu, Fang Liu, Xiaofen Xing, Lin Wang
2022 J jnl
CoRR
Kailing Guo, Zhenquan Lin, Xiaofen Xing, Fang Liu, Xiangmin Xu
2022 J jnl
IEEE ACM Trans. Audio Speech Lang. Process.
Weiquan Fan, Xiangmin Xu, Bolun Cai, Xiaofen Xing
2022 J jnl
Neurocomputing
Fang Liu, Xiangmin Xu, Xiaofen Xing, Kailing Guo, Lin Wang
2022 A conf
INTERSPEECH
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2022 J jnl
CoRR
Weidong Chen, Xiaofen Xing, Xiangmin Xu, Jianxin Pang, Lan Du
2021 J jnl
Neurocomputing
Pengqian Li, Xiaofen Xing, Xiangmin Xu, Bolun Cai, Jun Cheng
2021 conf
ICMI Companion
Zhiwei He, Xiangmin Xu, Xiaofen Xing, Yirong Chen, Wenjing Han
2021 conf
APSIPA ASC
Ruitong Xiao, Xiaofen Xing, Jichen Yang, Xiangmin Xu
2021 A conf
Interspeech
Zhenchuan Yang, Weibin Zhang, Yufei Liu, Xiaofen Xing
2021 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Tong Zhang, Guoxi Su, Chunmei Qing, Xiangmin Xu, Bolun Cai, Xiaofen Xing
2021 Misc conf
ICASSP
Weiquan Fan, Xiangmin Xu, Xiaofen Xing, Weidong Chen, Dongyan Huang
2021 J jnl
CoRR
Weiquan Fan, Xiangmin Xu, Xiaofen Xing, Weidong Chen, Dongyan Huang
2021 conf
ACAI
Fang Liu, Feifei Qi, Xiaofen Xing, Kailing Guo
2021 J jnl
Neurocomputing
Shuzhen Li, Xiaofen Xing, Weiquan Fan, Bolun Cai, Perry Fordson, Xiangmin Xu
2021 conf
APSIPA ASC
Weirui Lu, Xiaofen Xing, Xiangmin Xu, Weibin Zhang
2021 B conf
FG
Shaoping Jiang, Xiangmin Xu, Xiaofen Xing, Lin Wang, Fang Liu
2021 B conf
FG
Yaoli Wen, Xiangmin Xu, Fang Liu, Xiaofen Xing, Lin Wang
2021 A* conf
ACM Multimedia
Zhenquan Lin, Kailing Guo, Xiaofen Xing, Xiangmin Xu
2021 J jnl
CoRR
Zhenquan Lin, Kailing Guo, Xiaofen Xing, Xiangmin Xu
2020 A conf
INTERSPEECH
Weiquan Fan, Xiangmin Xu, Xiaofen Xing, Dongyan Huang
2020 Misc conf
ICASSP
Hanzao Chen, Xiaofen Xing, Xiangmin Xu
2019 J jnl
CoRR
Bolun Cai, Xiangmin Xu, Xiaofen Xing, Kui Jia, Jie Miao, Dacheng Tao
2019 J jnl
IEEE Access
Kailing Guo, Xiaona Xie, Xiangmin Xu, Xiaofen Xing
2019 J jnl
IEEE Access
Haojie Li, Sihang Wu, Shuangping Huang, Kin-Man Lam, Xiaofen Xing
2019 J jnl
IEEE Access
Weirui Lu, Xiaofen Xing, Bolun Cai, Xiangmin Xu
2019 J jnl
CoRR
Weirui Lu, Xiaofen Xing, Bolun Cai, Xiangmin Xu
2019 J jnl
IEEE Access
Kailing Guo, Tong Zhang, Xiangmin Xu, Xiaofen Xing
2019 conf
AVEC@MM
Weiquan Fan, Zhiwei He, Xiaofen Xing, Bolun Cai, Weirui Lu
2019 conf
ACII Workshops
Lin Wang, Xiangmin Xu, Fang Liu, Xiaofen Xing, Bolun Cai, Weirui Lu
2019 J jnl
Frontiers Neurorobotics
Xiaofen Xing, Zhenqi Li, Tianyuan Xu, Lin Shu, Bin Hu, Xiangmin Xu
2018 A conf
ICME
Jiangfeng Xiong, Xiangmin Xu, Bolun Cai, Xiaofen Xing, Kailing Guo
2018 conf
AVEC@MM
Xiaofen Xing, Bolun Cai, Yinhu Zhao, Shuzhen Li, Zhiwei He, Weiquan Fan
2018 B conf
ICIP
Bolun Cai, Xiangmin Xu, Xiaofen Xing
2018 conf
ICME Workshops
Haoyu Li, Xiangmin Xu, Bolun Cai, Kailing Guo, Xiaofen Xing
2017 B conf
ICIP
Bolun Cai, Xiaofen Xing, Xiangmin Xu
2017 conf
iThings/GreenCom/CPSCom/SmartData
Xiaofen Xing, Guicong Xu, Bolun Cai, Chunmei Qing, Xiangmin Xu
2017 J jnl
CoRR
Jie Miao, Xiangmin Xu, Xiaofen Xing, Dacheng Tao
2017 J jnl
Multim. Tools Appl.
Xiaofen Xing, Fuhao Qiu, Xiangmin Xu, Chunmei Qing, Yinrong Wu
2016 J jnl
IEEE Trans. Image Process.
Bolun Cai, Xiangmin Xu, Xiaofen Xing, Kui Jia, Jie Miao, Dacheng Tao
2016 conf
CSNDSP
Xiaofen Xing, Nanhai Zhang, Kailing Guo, Chunmei Qing, Jiali Deng, Huiping Qin
2016 conf
PCM (2)
Jie Miao, Xiangmin Xu, Xiaoyi Jia, Haoyu Huang, Bolun Cai, Chunmei Qing, Xiaofen Xing
2016 conf
APSIPA
Qiyu Chen, Weibin Zhang, Xiangmin Xu, Xiaofen Xing
2015 conf
DSP
Xiaofen Xing, Fuhao Qiu, Xiangmin Xu, Chunmei Qing
2015 B conf
ICIP
Bolun Cai, Xiangmin Xu, Xiaofen Xing, Chunmei Qing
2015 conf
DSP
Guicong Xu, Xiangmin Xu, Xiaofen Xing, Bolun Cai, Chunmei Qing
2014 B conf
ICIP
Xiaoyi Zou, Xiangmin Xu, Chunmei Qing, Xiaofen Xing
2011 J jnl
Comput. Math. Methods Medicine
Zhuocai Wang, Xiangmin Xu, Xiaojun Ding, Hui Xiao, Yusheng Huang, Jian Liu, Xiaofen Xing, Hua Wang, D. Joshua Liao
redb/extractors/yara.py
← Index redb/extractors/yara.py python
"""
YARA Extractor - Scans binary files with YARA rules and stores matches in ClickHouse.

This extractor uses the yara-x library to scan samples against a collection of
YARA rules located in the 'yara/' folder at the project root.

Supports both:
- Pre-compiled rules (.yarac) for faster loading
- Source rules (.yar/.yara) compiled on-the-fly

Schema Design:
- yara_rules: Rule metadata stored once per unique rule (deduplicated by rule_id)
- yara_matches: Sample-rule matches with binary sha256 for efficiency
"""
import inspect
import json
import os
import re
import threading
import time
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple

import xxhash
import yara_x

from redb.extractors.enum import Tag
from redb.extractors.extractor import Extractor
from redb.models.dataclasses import YaraMatch, YaraRule


# Default compiled rules filename (can be overridden via YARA_COMPILED_RULES env var)
COMPILED_RULES_FILENAME = os.getenv("YARA_COMPILED_RULES", "compiled_rules.yarac")

# Default source collection name
DEFAULT_SOURCE_COLLECTION = os.getenv("YARA_SOURCE_COLLECTION", "default")


def canonicalize_rule(rule_text: str) -> str:
    """
    Canonicalize YARA rule text for consistent hashing.

    Strips comments and normalizes whitespace, but excludes metadata
    so rules with same logic but different metadata get the same ID.
    """
    # Strip single-line comments
    text = re.sub(r'//.*$', '', rule_text, flags=re.MULTILINE)
    # Strip multi-line comments
    text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
    # Strip meta section (keep only strings/condition)
    text = re.sub(r'meta\s*:\s*[^}]+(?=strings|condition|})', '', text, flags=re.DOTALL)
    # Normalize whitespace
    text = ' '.join(text.split())
    return text


def generate_rule_id(rule_text: str) -> int:
    """
    Generate a unique rule_id from canonicalized rule content.

    Returns:
        UInt64 hash of the canonical rule content
    """
    canonical = canonicalize_rule(rule_text)
    return xxhash.xxh64(canonical.encode('utf-8')).intdigest()


def sha256_hex_to_binary(hex_str: str) -> bytes:
    """Convert SHA256 hex string to binary (32 bytes)."""
    return bytes.fromhex(hex_str)


def sha256_binary_to_hex(binary: bytes) -> str:
    """Convert SHA256 binary (32 bytes) to hex string."""
    return binary.hex()


def parse_yara_rules(file_content: str) -> List[Dict[str, Any]]:
    """
    Parse individual YARA rules from file content.

    Handles files with multiple rules and extracts:
    - rule_name: The rule identifier
    - rule_tags: List of tags (from 'rule Name : tag1 tag2 {')
    - rule_meta: Dict of metadata key-value pairs
    - rule_text: Full rule source code

    Args:
        file_content: Raw content of a .yar/.yara file

    Returns:
        List of dicts, each containing rule_name, rule_tags, rule_meta, rule_text
    """
    rules = []

    # Pattern to match rule declarations: rule Name or rule Name : tags
    # We need to find rule boundaries by tracking braces
    rule_pattern = re.compile(
        r'(?:^|\n)\s*((?:private\s+|global\s+)*rule\s+(\w+)\s*(?::\s*([^{]*))?\s*\{)',
        re.MULTILINE
    )

    matches = list(rule_pattern.finditer(file_content))

    for i, match in enumerate(matches):
        rule_start = match.start(1)  # Start of 'rule ...'
        rule_name = match.group(2)
        tags_str = match.group(3) or ""
        rule_tags = [t.strip() for t in tags_str.split() if t.strip()]

        # Find the matching closing brace by counting braces
        brace_count = 0
        rule_end = match.end()
        in_string = False
        escape_next = False

        for j, char in enumerate(file_content[match.end() - 1:], start=match.end() - 1):
            if escape_next:
                escape_next = False
                continue
            if char == '\\':
                escape_next = True
                continue
            if char == '"' and not escape_next:
                in_string = not in_string
                continue
            if in_string:
                continue
            if char == '{':
                brace_count += 1
            elif char == '}':
                brace_count -= 1
                if brace_count == 0:
                    rule_end = j + 1
                    break

        rule_text = file_content[rule_start:rule_end].strip()

        # Extract metadata from rule
        meta = {}
        meta_match = re.search(
            r'meta\s*:\s*(.*?)(?=strings\s*:|condition\s*:|$)',
            rule_text,
            re.DOTALL
        )
        if meta_match:
            meta_text = meta_match.group(1)
            for line in meta_text.strip().split('\n'):
                if '=' in line:
                    key, _, value = line.partition('=')
                    key = key.strip()
                    value = value.strip().strip('"\'')
                    if key and not key.startswith('//'):
                        meta[key] = value

        rules.append({
            'rule_name': rule_name,
            'rule_tags': rule_tags,
            'rule_meta': meta,
            'rule_text': rule_text,
        })

    return rules


class YaraBatchInsertBuffer:
    """
    Thread-safe buffer for batching YARA match inserts.

    Collects matches from multiple samples and flushes to ClickHouse
    when batch_size is reached or flush_interval expires.
    """

    def __init__(
        self,
        exporter,
        index_prefix: str,
        batch_size: int = 1000,
        flush_interval: int = 30,
    ):
        self.exporter = exporter
        self.index_prefix = index_prefix
        self.batch_size = batch_size
        self.flush_interval = flush_interval

        self.matches_buffer: List[List] = []
        self.rules_buffer: Dict[int, List] = {}  # rule_id -> rule_data (deduplicated)
        self.lock = threading.Lock()
        self.last_flush = time.time()

        # Start background flush timer
        self._stop_timer = False
        self._timer_thread = threading.Thread(target=self._flush_timer, daemon=True)
        self._timer_thread.start()

    def add(self, sha256_binary: bytes, matches: List[Tuple], rules: Dict[int, List]) -> None:
        """
        Add matches and rules to buffer.

        Args:
            sha256_binary: Binary SHA256 (32 bytes)
            matches: List of match tuples (sha256_binary, rule_id, rule_name, scan_date, match_strings)
            rules: Dict of rule_id -> rule_data tuples
        """
        with self.lock:
            self.matches_buffer.extend(matches)
            # Merge rules (deduplicated by rule_id)
            for rule_id, rule_data in rules.items():
                if rule_id not in self.rules_buffer:
                    self.rules_buffer[rule_id] = rule_data

            if len(self.matches_buffer) >= self.batch_size:
                self._flush_locked()

    def _flush_locked(self) -> None:
        """Flush buffer (must hold lock)."""
        if not self.matches_buffer:
            return

        try:
            # Insert rules first (deduplicated)
            if self.rules_buffer:
                rules_data = list(self.rules_buffer.values())
                self.exporter.batch_insert(
                    table='yara_rules',
                    rows=rules_data,
                    column_names=[
                        'rule_id', 'rule_name', 'source_collection',
                        'ingested_at', 'rule_text', 'rule_meta', 'rule_tags'
                    ],
                    column_type_names=[
                        'UInt64', 'String', 'LowCardinality(String)',
                        "DateTime64(3, 'UTC')", 'String', 'JSON', 'Array(LowCardinality(String))'
                    ]
                )

            # Insert matches
            self.exporter.batch_insert(
                table='yara_matches',
                rows=self.matches_buffer,
                column_names=[
                    'sha256', 'rule_id', 'rule_name',
                    'scan_date', 'match_strings'
                ],
                column_type_names=[
                    'FixedString(32)', 'UInt64', 'LowCardinality(String)',
                    "DateTime64(3, 'UTC')", 'Array(String)'
                ]
            )

            print(f"[YARA] Flushed {len(self.matches_buffer)} matches and {len(self.rules_buffer)} rules")

        except Exception as e:
            print(f"[YARA] Error flushing batch: {e}")

        # Clear buffers
        self.matches_buffer = []
        self.rules_buffer = {}
        self.last_flush = time.time()

    def flush(self) -> None:
        """Public flush (acquires lock)."""
        with self.lock:
            self._flush_locked()

    def _flush_timer(self) -> None:
        """Background timer for periodic flushes."""
        while not self._stop_timer:
            time.sleep(5)  # Check every 5 seconds
            with self.lock:
                if time.time() - self.last_flush > self.flush_interval and self.matches_buffer:
                    self._flush_locked()

    def stop(self) -> None:
        """Stop the background timer and flush remaining data."""
        self._stop_timer = True
        self.flush()


class YaraExtractor(Extractor):
    """
    Extractor that scans binary files with YARA rules.

    The YARA rules are loaded from the 'yara/' folder at the project root.
    Each matching rule is stored in ClickHouse with its metadata.

    Supports pre-compiled rules for faster loading:
    - If 'yara/compiled_rules.yarac' exists, it will be loaded directly
    - Otherwise, all .yar/.yara files are compiled and cached in memory
    - Use YaraExtractor.compile_and_save() to pre-compile rules
    """

    # Class-level cache for compiled YARA rules
    _compiled_rules = None
    _rules_path = None

    def __init__(
        self,
        filepath: str,
        log: Any,
        exporters: Optional[List] = None,
        index_prefix: Optional[str] = None,
        known_benign: bool = False,
        known_malicious: bool = False,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            known_benign,
            known_malicious,
        )
        self.matches: List[YaraMatch] = []
        self.rules: Dict[str, YaraRule] = {}  # rule_name -> YaraRule (deduplicated)

    @classmethod
    def get_yara_rules_path(cls) -> Path:
        """Get the path to the YARA rules directory."""
        # Default to 'yara/' in project root
        project_root = Path(__file__).parent.parent.parent
        default_path = project_root / "yara"

        # Allow override via environment variable
        rules_path = os.getenv("YARA_RULES_PATH", str(default_path))
        return Path(rules_path)

    @classmethod
    def get_compiled_rules_path(cls) -> Path:
        """Get the path to the pre-compiled rules file."""
        return cls.get_yara_rules_path() / COMPILED_RULES_FILENAME

    @classmethod
    def load_compiled_rules(cls) -> Optional[yara_x.Rules]:
        """
        Load pre-compiled YARA rules from .yarac file.

        Returns:
            Compiled Rules object or None if file doesn't exist
        """
        compiled_path = cls.get_compiled_rules_path()
        if not compiled_path.exists():
            return None

        try:
            with open(compiled_path, "rb") as f:
                rules = yara_x.Rules.deserialize_from(f)
            # Only log in debug mode (non-prod) to avoid spamming in bulk processing
            if os.getenv("SERVER_ENV") != "prod":
                print(f"[DEBUG] Loaded pre-compiled YARA rules from {compiled_path}")
            return rules
        except Exception as e:
            print(f"[WARNING] Failed to load compiled rules from {compiled_path}: {e}")
            return None

    @classmethod
    def compile_rules_from_source(cls) -> Optional[yara_x.Rules]:
        """
        Compile all YARA rules from source .yar/.yara files.

        Returns:
            Compiled Rules object or None if no rules found
        """
        rules_path = cls.get_yara_rules_path()

        if not rules_path.exists():
            return None

        # Find all .yar and .yara files recursively
        rule_files = []
        for ext in ["*.yar", "*.yara"]:
            rule_files.extend(rules_path.rglob(ext))

        if not rule_files:
            return None

        print(f"[INFO] Compiling {len(rule_files)} YARA rule files from {rules_path}")

        # Compile all rules using yara-x compiler
        compiler = yara_x.Compiler()
        compiled_count = 0
        failed_count = 0

        for rule_file in rule_files:
            try:
                with open(rule_file, "r", encoding="utf-8") as f:
                    rule_content = f.read()
                # Use the relative path from rules_path as namespace
                namespace = str(rule_file.relative_to(rules_path).parent)
                if namespace == ".":
                    namespace = "default"
                compiler.new_namespace(namespace)
                compiler.add_source(rule_content)
                compiled_count += 1
            except Exception as e:
                # Log warning but continue with other rules
                print(f"[WARNING] Failed to compile YARA rule {rule_file}: {e}")
                failed_count += 1
                continue

        try:
            rules = compiler.build()
            print(f"[INFO] Successfully compiled {compiled_count} rule files ({failed_count} failed)")
            return rules
        except Exception as e:
            print(f"[ERROR] Failed to build YARA rules: {e}")
            return None

    @classmethod
    def compile_rules(cls, force_reload: bool = False) -> Optional[yara_x.Rules]:
        """
        Get compiled YARA rules, loading from cache, .yarac file, or compiling from source.

        Priority:
        1. Return cached rules if available
        2. Load pre-compiled .yarac file if it exists
        3. Compile from source .yar/.yara files

        Args:
            force_reload: If True, ignore cache and reload rules

        Returns:
            Compiled YARA rules or None if no rules found
        """
        rules_path = cls.get_yara_rules_path()

        # Return cached rules if available and path hasn't changed
        if (
            cls._compiled_rules is not None
            and cls._rules_path == rules_path
            and not force_reload
        ):
            return cls._compiled_rules

        # Try loading pre-compiled rules first
        rules = cls.load_compiled_rules()

        # If no pre-compiled rules, compile from source
        if rules is None:
            rules = cls.compile_rules_from_source()

        # Cache the rules
        if rules is not None:
            cls._compiled_rules = rules
            cls._rules_path = rules_path

        return rules

    @classmethod
    def compile_and_save(cls, output_path: Optional[Path] = None) -> bool:
        """
        Compile all YARA rules from source and save to a .yarac file.

        This is useful for pre-compiling rules for faster loading in production.

        Args:
            output_path: Path to save compiled rules (default: yara/compiled_rules.yarac)

        Returns:
            True if successful, False otherwise
        """
        if output_path is None:
            output_path = cls.get_compiled_rules_path()

        # Force compile from source
        rules = cls.compile_rules_from_source()
        if rules is None:
            print("[ERROR] No rules to compile")
            return False

        try:
            # Ensure parent directory exists
            output_path.parent.mkdir(parents=True, exist_ok=True)

            with open(output_path, "wb") as f:
                rules.serialize_into(f)

            print(f"[INFO] Saved compiled YARA rules to {output_path}")
            return True
        except Exception as e:
            print(f"[ERROR] Failed to save compiled rules: {e}")
            return False

    def _extract_yara_matches(self) -> Tuple[List[YaraMatch], Dict[str, YaraRule]]:
        """
        Scan the binary with compiled YARA rules.

        Returns:
            Tuple of (matches list, rules dict) for each matching rule
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        compiled_rules = self.compile_rules()
        if compiled_rules is None:
            self.log.warning("No YARA rules found or compiled")
            return [], {}

        matches = []
        rules = {}

        try:
            # Scan the binary data
            scan_results = compiled_rules.scan(self.binary)

            # Process each matching rule
            for rule in scan_results.matching_rules:
                rule_name = rule.identifier

                # Extract rule metadata and store rule (deduplicated by name)
                if rule_name not in rules:
                    meta = {}
                    for identifier, value in rule.metadata:
                        meta[identifier] = str(value)
                    rules[rule_name] = YaraRule(
                        rule_name=rule_name,
                        rule_tags=list(rule.tags),
                        rule_meta=meta,
                    )

                # Extract matched string identifiers
                matched_strings = []
                for pattern in rule.patterns:
                    for match in pattern.matches:
                        matched_strings.append(pattern.identifier)

                # Remove duplicates from matched strings
                matched_strings = list(set(matched_strings))

                yara_match = YaraMatch(
                    rule_name=rule_name,
                    match_strings=matched_strings,
                )
                matches.append(yara_match)

                self.log.debug(
                    f"YARA match: {rule_name} (tags: {list(rule.tags)})"
                )

        except Exception as e:
            self.log.error(f"Error scanning with YARA: {e}")
            return [], {}

        return matches, rules

    def extract(self) -> Optional[List[YaraMatch]]:
        """
        Extract YARA matches from the binary.

        Returns:
            List of YaraMatch objects or None on error
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            self.matches, self.rules = self._extract_yara_matches()
            return self.matches if self.matches else None
        except Exception as e:
            self.log.error(f"Error extracting YARA matches: {e}")
            return None

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.YARA.value

    def get_clickhouse_table(self) -> str:
        """Return the ClickHouse table name for YARA matches."""
        return "yara_matches"

    def get_clickhouse_tables(self) -> Dict[str, str]:
        """Return all ClickHouse table names for multi-table support."""
        return {
            'rules': 'yara_rules',
            'matches': 'yara_matches',
        }

    def prepare_export_data(self, exporter_type: str) -> Any:
        """
        Prepare data for export to the specified exporter type.

        Uses optimized normalized schema with two tables:
        - yara_rules: Rule metadata with rule_id (UInt64 hash)
        - yara_matches: Matches with binary sha256 (32 bytes) and rule_id

        Args:
            exporter_type: The type of exporter (e.g., 'ClickHouseExporter')

        Returns:
            Data formatted for the specified exporter
        """

        if exporter_type == "ClickHouseExporter":
            if not self.matches:
                return None

            current_time = datetime.now(timezone.utc)
            source_collection = DEFAULT_SOURCE_COLLECTION

            # Convert sha256 hex to binary (32 bytes)
            sha256_binary = sha256_hex_to_binary(self.sha256)

            # Build rules data from self.rules (deduplicated by rule_id)
            rules_data = {}  # rule_id -> rule_data
            for rule_name, rule in self.rules.items():
                rule_content = f"rule {rule_name} {{ }}"  # Simplified for now
                rule_id = generate_rule_id(rule_content)
                if rule_id not in rules_data:
                    rules_data[rule_id] = [
                        rule_id,
                        rule.rule_name,
                        source_collection,
                        current_time,  # ingested_at
                        "",  # rule_text (empty for now, populated during sync)
                        json.dumps(rule.rule_meta),
                        rule.rule_tags,
                    ]

            # Build matches data
            matches_data = []
            for match in self.matches:
                rule_content = f"rule {match.rule_name} {{ }}"
                rule_id = generate_rule_id(rule_content)

                matches_data.append([
                    sha256_binary,  # Binary sha256 (32 bytes)
                    rule_id,
                    match.rule_name,
                    current_time,  # scan_date
                    match.match_strings,
                ])

            return {
                'multi_table': True,
                'rules': {
                    'table': 'yara_rules',
                    'data': list(rules_data.values()),
                    'column_names': [
                        'rule_id',
                        'rule_name',
                        'source_collection',
                        'ingested_at',
                        'rule_text',
                        'rule_meta',
                        'rule_tags',
                    ],
                    'column_type_names': [
                        'UInt64',
                        'String',
                        'LowCardinality(String)',
                        "DateTime64(3, 'UTC')",
                        'String',
                        'JSON',
                        'Array(LowCardinality(String))',
                    ],
                },
                'matches': {
                    'table': 'yara_matches',
                    'data': matches_data,
                    'column_names': [
                        'sha256',
                        'rule_id',
                        'rule_name',
                        'scan_date',
                        'match_strings',
                    ],
                    'column_type_names': [
                        'FixedString(32)',  # Binary sha256
                        'UInt64',
                        'LowCardinality(String)',
                        "DateTime64(3, 'UTC')",
                        'Array(String)',
                    ],
                },
            }

        return None


def sync_rules_to_db(source_collection: str = None) -> bool:
    """
    Sync all YARA rules from source files to the database.

    This ensures all rules exist in yara_rules table before scanning begins.
    Should be run before batch scanning or in container initialization.

    Args:
        source_collection: Source collection name (default from env)

    Returns:
        True if successful, False otherwise
    """
    from redb import settings

    source_collection = source_collection or DEFAULT_SOURCE_COLLECTION
    rules_path = YaraExtractor.get_yara_rules_path()

    if not rules_path.exists():
        print(f"[ERROR] Rules path does not exist: {rules_path}")
        return False

    # Find all rule files
    rule_files = []
    for ext in ["*.yar", "*.yara"]:
        rule_files.extend(rules_path.rglob(ext))

    if not rule_files:
        print(f"[INFO] No rule files found in {rules_path}")
        return True

    print(f"[INFO] Syncing {len(rule_files)} rule files to database...")

    current_time = datetime.now(timezone.utc)
    rules_data = []
    total_rules = 0

    for rule_file in rule_files:
        try:
            with open(rule_file, "r", encoding="utf-8") as f:
                file_content = f.read()

            # Parse individual rules from file (handles multiple rules per file)
            parsed_rules = parse_yara_rules(file_content)

            for rule in parsed_rules:
                rule_id = generate_rule_id(rule['rule_text'])

                rules_data.append([
                    rule_id,
                    rule['rule_name'],
                    source_collection,
                    current_time,
                    rule['rule_text'],
                    json.dumps(rule['rule_meta']),
                    rule['rule_tags'],
                ])
                total_rules += 1

        except Exception as e:
            print(f"[WARNING] Failed to parse rule file {rule_file}: {e}")
            continue

    print(f"[INFO] Parsed {total_rules} individual rules from {len(rule_files)} files")

    if not rules_data:
        print("[INFO] No rules to sync")
        return True

    # Insert rules to database
    try:
        client = settings.create_clickhouse_client()
        table = "yara_rules"

        client.insert(
            table,
            rules_data,
            column_names=[
                'rule_id', 'rule_name', 'source_collection',
                'ingested_at', 'rule_text', 'rule_meta', 'rule_tags'
            ],
            column_type_names=[
                'UInt64', 'String', 'LowCardinality(String)',
                "DateTime64(3, 'UTC')", 'String', 'JSON', 'Array(LowCardinality(String))'
            ]
        )

        print(f"[INFO] Successfully synced {len(rules_data)} rules to {table}")
        client.close()
        return True

    except Exception as e:
        print(f"[ERROR] Failed to sync rules to database: {e}")
        return False


# CLI utility for pre-compiling rules and syncing
if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="YARA Rules Management Utility")
    parser.add_argument(
        "--compile",
        action="store_true",
        help="Compile all YARA rules and save to .yarac file",
    )
    parser.add_argument(
        "--sync-rules",
        action="store_true",
        help="Sync all YARA rules to the database (run before batch scanning)",
    )
    parser.add_argument(
        "--output",
        type=str,
        help="Output path for compiled rules (default: yara/compiled_rules.yarac)",
    )
    parser.add_argument(
        "--rules-path",
        type=str,
        help="Path to YARA rules directory (default: yara/)",
    )
    parser.add_argument(
        "--source-collection",
        type=str,
        help="Source collection name for rules (default: from YARA_SOURCE_COLLECTION env)",
    )

    args = parser.parse_args()

    if args.rules_path:
        os.environ["YARA_RULES_PATH"] = args.rules_path

    if args.compile:
        output_path = Path(args.output) if args.output else None
        success = YaraExtractor.compile_and_save(output_path)
        if not success:
            exit(1)

    if args.sync_rules:
        success = sync_rules_to_db(args.source_collection)
        if not success:
            exit(1)

    if not args.compile and not args.sync_rules:
        parser.print_help()