import os
import sys
import ast
import importlib
import subprocess
import tempfile
import time

def is_python_file(path=None, content=None):
    if path:
        return os.path.splitext(path)[1].lower() == '.py'
    if content:
        return 'import' in content
    return False
def wait_for_exit(seconds):
    """等待用户输入或计时结束"""
    try:
        # 如果是Windows系统
        if os.name == 'nt':
            import msvcrt
            print(f"\n程序将在 {seconds} 秒后自动退出，按回车或空格键立即退出...")
            for i in range(seconds):
                if msvcrt.kbhit():
                    key = msvcrt.getch()
                    # 检查是否是回车键或空格键
                    if key in [b'\r', b'\n', b' ']:
                        break
                time.sleep(1)
        else:
            # 非Windows系统
            import select
            while seconds > 0:
                print(f"\r程序将在 {seconds} 秒后自动退出，按回车或空格键立即退出...", end="")
                try:
                    # 等待用户输入，最多等待1秒
                    if sys.stdin in select.select([sys.stdin], [], [], 1)[0]:
                        input()
                        return
                    seconds -= 1
                except:
                    # 如果select不可用，则使用简单的sleep
                    time.sleep(1)
                    seconds -= 1
    except:
        # 如果上述方法都失败，使用最简单的等待
        input("\n按回车键退出...")


import ast
import sys

def parse_libraries(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            tree = ast.parse(f.read())
    except Exception as e:
        print(f"解析文件 {file_path} 失败: {e}")
        return []
    
    # 导入名与安装名的映射字典
    import_to_install_map = {
        'sklearn': 'scikit-learn',
        'PIL': 'pillow',
        'cv2': 'opencv-python',
        'bs4': 'beautifulsoup4',
        'yaml': 'pyyaml',
        'googleapiclient': 'google-api-python-client',
        'wx': 'wxpython',
        'dotenv': 'python-dotenv',
        'jwt': 'pyjwt',
        'dateutil': 'python-dateutil',
        'flask_sqlalchemy': 'flask-sqlalchemy',
        'skimage': 'scikit-image',
        'netCDF4': 'netcdf4',
        'psycopg2': 'psycopg2-binary',
        'mx': 'mxnet',
        'tf': 'tensorflow',
        'bs': 'beautifulsoup4',
        'pil': 'pillow',
        'pg': 'pygresql',
        'pptx': 'python-pptx',
        'docx': 'python-docx',
        'pycrypto': 'pycryptodome',
        'redis': 'redis-py',
        'matplotlib.pyplot': 'matplotlib',
        'mpl_toolkits': 'matplotlib',
        'h5py': 'h5py',
        'scipy.sparse': 'scipy',
        'requests_oauthlib': 'requests-oauthlib',
        'httpx': 'httpx',
        'joblib': 'joblib',
        'jinja2': 'jinja2',
        'tweepy': 'tweepy',
        'xgboost': 'xgboost',
        'lightgbm': 'lightgbm',
        'catboost': 'catboost',
        'spacy': 'spacy',
        'nltk': 'nltk',
        'tqdm': 'tqdm',
        'seaborn': 'seaborn',
        'altair': 'altair',
        'bokeh': 'bokeh',
        'sqlalchemy': 'sqlalchemy',
        'pyspark': 'pyspark',
        'statsmodels': 'statsmodels',
        'plotly': 'plotly',
        'gensim': 'gensim',
        'theano': 'theano',
        'openpyxl': 'openpyxl',
        'xlrd': 'xlrd',
        'bcrypt': 'bcrypt',
        'cairosvg': 'cairosvg',
        'pydot': 'pydot',
        'wordcloud': 'wordcloud'
    }
    
    libraries = set()
    builtin_libs = set(sys.builtin_module_names)
    
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            for name in node.names:
                lib = name.name.split('.')[0]
                if lib not in builtin_libs and lib not in {'import', 'from', 'as'}:
                    # 查找正确的安装名称
                    install_name = import_to_install_map.get(lib, lib)
                    libraries.add(install_name)
        elif isinstance(node, ast.ImportFrom):
            if node.module is not None:  # 防止from . import x这类相对导入
                lib = node.module.split('.')[0]
                if lib not in builtin_libs and lib not in {'import', 'from', 'as'}:
                    # 查找正确的安装名称
                    install_name = import_to_install_map.get(lib, lib)
                    libraries.add(install_name)
    
    return list(libraries)


def install_dependencies(missing_libs, source=None):
    python_exe = sys.executable

    # 第一阶段：先安装 pyperclip
    required_libs = ['pyperclip']
    for lib in required_libs:
        try:
            importlib.import_module(lib)
            print(f"库 {lib} 已安装")
        except ImportError:
            print(f"正在安装 {lib}...")
            result = subprocess.run([python_exe, '-m', 'pip', 'install', lib, '-i', 'https://pypi.mirrors.ustc.edu.cn/simple/', '--trusted-host', 'pypi.mirrors.ustc.edu.cn'], capture_output=True, text=True)
            if result.returncode == 0:
                print(f"成功安装的库: {lib}")
                try:
                    importlib.import_module(lib)
                except ImportError:
                    print(f"错误: {lib} 安装成功但导入失败，程序退出")
                    return False
            else:
                print(f"安装 {lib} 失败: {result.stderr}")
                print("核心依赖安装失败，程序退出")
                return False
    
    # 第二阶段：安装其他缺失库
    for lib in missing_libs:
        try:
            importlib.import_module(lib)
            print(f"库 {lib} 已安装")
        except ImportError:
            print(f"正在安装 {lib}...")
            pip_args = [python_exe, '-m', 'pip', 'install', lib, '-i', 'https://pypi.mirrors.ustc.edu.cn/simple/', '--trusted-host', 'pypi.mirrors.ustc.edu.cn']
            if source:
                pip_args.extend(['-i', source])
            result = subprocess.run(pip_args, capture_output=True, text=True)
            if result.returncode == 0:
                print(f"成功安装的库: {lib}")
            else:
                print(f"安装 {lib} 失败: {result.stderr}")
    return True

def main():
    if len(sys.argv) > 1:
        file_path = sys.argv[1]
        print(f"接收到的目标文件路径: {file_path}")

    else:
        file_path = None
    
    libraries = parse_libraries(file_path)

 
    if not libraries:
        print("未检测到任何外部库")
        return

    missing_libs = []
    for lib in libraries:
        try:
            importlib.import_module(lib)
        except ImportError:
            missing_libs.append(lib)
    
    if missing_libs:
        print(f"检测到未安装的库: {', '.join(missing_libs)}")
        if len(sys.argv) > 1:
            file_path = sys.argv[1]
        else:
            file_path = None
        
        # 默认使用国内源，例如清华源，用户参数可覆盖
        source = sys.argv[2] if len(sys.argv) > 2 else 'https://pypi.tuna.tsinghua.edu.cn/simple'
        # ... 其余代码不变
        install_dependencies(missing_libs, source)
    else:
        print("===============  所有依赖已安装  ===============")   

    # wait_for_exit(15)
    #
    #
    # os.unlink(temp_file)

if __name__ == '__main__':
    main()