# -*- coding: utf-8 -*-
"""
MailBot Agent 打包脚本
生成一个通用exe + 每个账号的config.ini配置模板
用法: python build_all.py
"""
import os
import sys
import shutil
import subprocess
import configparser

ACCOUNTS = ['TT', 'KK', 'YY']

SOURCE_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'mailbot_agent.py')
DIST_DIR = r'D:\EXE\test_exe\新建文件夹'

PYINSTALLER = r'D:\Python3.8\Scripts\pyinstaller.exe'

SERVER_HOST = '192.168.2.55'
SERVER_PORT = '8000'

EXCLUDE_MODULES = [
    'numpy', 'pandas', 'matplotlib', 'scipy', 'PIL', 'Pillow',
    'scrapy', 'twisted', 'lxml', 'beautifulsoup4', 'bs4',
    'flask', 'fastapi', 'gradio', 'uvicorn', 'starlette',
    'kafka', 'redis', 'sqlalchemy', 'SQLAlchemy',
    'jupyter', 'notebook', 'ipython', 'ipykernel', 'ipywidgets',
    'openai', 'spacy', 'nltk', 'jieba',
    'gevent', 'aiohttp', 'httpx', 'httpcore',
    'selenium', 'DrissionPage', 'DataRecorder', 'DownloadKit',
    'paramiko', 'psycopg2', 'PyMySQL', 'mysql',
    'cryptography', 'pyOpenSSL',
    'curl_cffi', 'Brotli', 'h2', 'hpack', 'hyper', 'hyperframe',
    'ddddocr', 'imgaug', 'imageio',
    'pydantic', 'pydantic_core',
    'Js2Py', 'fire', 'loguru', 'tqdm',
    'orjson', 'msgpack', 'flatbuffers', 'grpcio', 'protobuf',
    'Cython', 'decompyle3',
    'amazoncaptcha', 'keepa', 'jqdatasdk',
    'parsel', 'cssselect', 'w3lib',
    'ephem', 'convertdate', 'holidays', 'LunarCalendar',
    'Faker', 'fake_useragent',
    'geventhttpclient', 'browsermob_proxy',
    'Babel', 'colorama', 'colour',
    'func_timeout', 'DBUtils',
    'tkinter', '_tkinter',
]


def build_exe():
    """打包通用exe"""
    print('\n' + '=' * 60)
    print('  打包: MailBot_Agent.exe (通用版)')
    print('=' * 60)

    exe_name = 'MailBot_Agent'
    base_dir = os.path.dirname(os.path.abspath(__file__))
    work_dir = os.path.join(base_dir, 'build')

    cmd_list = [
        PYINSTALLER, '--onefile', '--noconsole',
        '--name', exe_name,
        '--distpath', DIST_DIR,
        '--workpath', work_dir,
        '--specpath', base_dir,
        '--clean', '-y',
    ]
    for m in EXCLUDE_MODULES:
        cmd_list.extend(['--exclude-module', m])
    cmd_list.append(SOURCE_FILE)

    print('  [执行] pyinstaller --onefile --noconsole --name {} + {} excludes'.format(
        exe_name, len(EXCLUDE_MODULES)))
    result = subprocess.run(
        cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        encoding='utf-8', errors='ignore')
    if result.returncode != 0:
        print('  [错误] PyInstaller 打包失败, 返回码={}'.format(result.returncode))
        err_lines = (result.stderr or result.stdout or '').strip().split('\n')
        for line in err_lines[-10:]:
            print('    {}'.format(line))
        return False

    exe_path = os.path.join(DIST_DIR, '{}.exe'.format(exe_name))
    if os.path.exists(exe_path):
        size_mb = os.path.getsize(exe_path) / 1024 / 1024
        print('  [成功] {} ({:.1f} MB)'.format(exe_path, size_mb))
        return True
    else:
        print('  [错误] exe 未生成: {}'.format(exe_path))
        return False


def generate_configs():
    """为每个账号生成部署目录: exe + config.ini"""
    print('\n' + '=' * 60)
    print('  生成账号部署目录')
    print('=' * 60)

    exe_src = os.path.join(DIST_DIR, 'MailBot_Agent.exe')

    for acc in ACCOUNTS:
        acc_dir = os.path.join(DIST_DIR, acc)
        if not os.path.exists(acc_dir):
            os.makedirs(acc_dir)

        config = configparser.ConfigParser()
        config.optionxform = str
        config.add_section('agent')
        config.set('agent', 'account', acc)
        config.set('agent', 'server_host', SERVER_HOST)
        config.set('agent', 'server_port', SERVER_PORT)
        config.set('agent', 'token', '')
        config.set('agent', 'token_expire', '')

        config_path = os.path.join(acc_dir, 'config.ini')
        with open(config_path, 'w', encoding='utf-8') as f:
            config.write(f)

        exe_dst = os.path.join(acc_dir, 'MailBot_Agent.exe')
        shutil.copy2(exe_src, exe_dst)

        print('  [生成] {}/ -> MailBot_Agent.exe + config.ini (account={})'.format(acc, acc))


def cleanup():
    base_dir = os.path.dirname(os.path.abspath(__file__))
    for name in ['build', '__pycache__']:
        p = os.path.join(base_dir, name)
        if os.path.exists(p):
            shutil.rmtree(p, ignore_errors=True)
    for f in os.listdir(base_dir):
        if f.endswith('.spec'):
            os.remove(os.path.join(base_dir, f))


if __name__ == '__main__':
    print('MailBot Agent 打包 (通用exe + 配置文件)')
    print('账号列表: {}'.format(ACCOUNTS))
    print('源文件: {}'.format(SOURCE_FILE))
    print('PyInstaller: {}'.format(PYINSTALLER))
    print('输出目录: {}'.format(DIST_DIR))

    if not os.path.exists(SOURCE_FILE):
        print('[错误] 源文件不存在: {}'.format(SOURCE_FILE))
        sys.exit(1)

    if not os.path.exists(PYINSTALLER):
        print('[错误] PyInstaller 不存在: {}'.format(PYINSTALLER))
        print('请先安装: pip install pyinstaller')
        sys.exit(1)

    ok = build_exe()
    cleanup()

    if ok:
        generate_configs()
        print('\n' + '=' * 60)
        print('  打包完成!')
        print('=' * 60)
        print('  通用exe: {}'.format(os.path.join(DIST_DIR, 'MailBot_Agent.exe')))
        print('')
        for acc in ACCOUNTS:
            print('  {}/ -> MailBot_Agent.exe + config.ini'.format(acc))
        print('')
        print('  部署: 将对应账号文件夹复制到目标机器即可')
        print('  更新: 只需替换 MailBot_Agent.exe, config.ini 不动')
        print('=' * 60)
    else:
        print('\n[错误] 打包失败')
        sys.exit(1)
