#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@文件    :setup.py
@时间    :2022/02/21 17:00:46
@作者    :None
@版本    :1.0
@说明    :源码编译文件
'''


import sys
import os
import shutil
import time
from distutils.core import setup
from Cython.Build import cythonize

# import zipextimporter

start_time = time.time()
curr_dir = os.path.abspath('.')
parent_path = sys.argv[1] if len(sys.argv) > 1 else ""
setup_file = __file__.replace('/', '')
build_dir = "build"
build_tmp_dir = build_dir + "/temp"

s = "# cython: language_level=3"

"""
获取py文件的路径
:param base_path: 根路径
:param parent_path: 父路径
:param excepts: 排除文件
:return: py文件的迭代器
"""


def get_py(base_path=os.path.abspath('.'), parent_path='', name='', excepts=(), copyOther=False, delC=False):

    full_path = os.path.join(base_path, parent_path, name)
    for filename in os.listdir(full_path):
        full_filename = os.path.join(full_path, filename)
        if os.path.isdir(full_filename) and filename != build_dir and not filename.startswith('.'):
            for f in get_py(base_path, os.path.join(parent_path, name), filename, excepts, copyOther, delC):
                yield f
        elif os.path.isfile(full_filename):
            ext = os.path.splitext(filename)[1]
            if ext == ".c":
                if delC and os.stat(full_filename).st_mtime > start_time:
                    os.remove(full_filename)
            elif full_filename not in excepts and os.path.splitext(filename)[1] not in ('.pyc', '.pyx'):
                if os.path.splitext(filename)[1] in ('.py', '.pyx') and not filename.startswith('__'):
                    path = os.path.join(parent_path, name, filename)
                    yield path
        else:
            pass


def pack_pyd():
    # 获取py列表
    module_list = list(get_py(base_path=curr_dir, parent_path=parent_path, excepts=(setup_file,)))
    try:
        setup(
            ext_modules=cythonize(module_list, language_level="3"),
            script_args=["build_ext", "-b", build_dir, "-t", build_tmp_dir],
        )
    except Exception as ex:
        print("error! ", str(ex))
    else:
        module_list = list(get_py(base_path=curr_dir, parent_path=parent_path, excepts=(setup_file,), copyOther=True))

    module_list = list(get_py(base_path=curr_dir, parent_path=parent_path, excepts=(setup_file,), delC=True))
    if os.path.exists(build_tmp_dir):
        shutil.rmtree(build_tmp_dir)

    print("complate! time:", time.time() - start_time, 's')


"""
删除编译过程中生成的.c文件
:param path:
:param excepts:
:return:
"""


def delete_c(path='.', excepts=(setup_file,)):

    dirs = os.listdir(path)
    for dir in dirs:
        new_dir = os.path.join(path, dir)
        if os.path.isfile(new_dir):
            ext = os.path.splitext(new_dir)[1]
            if ext == '.c':
                os.remove(new_dir)
        elif os.path.isdir(new_dir):
            delete_c(new_dir)


if __name__ == '__main__':
    try:
        pack_pyd()
    except Exception as e:
        print(str(e))
    finally:
        delete_c()

# #!/usr/bin/env python
# # -*- coding:utf-8 -*-
# # @time: 2021/5/26 14:17
# # @File: create_pyd_file.py
# import os
# import shutil
# import time
# import sys


# def func(path):
#     folder_path = os.path.dirname(path)
#     file_path = os.path.split(path)[1]
#     os.chdir(folder_path)
#     with open('setup.py', 'w') as f:
#         f.write('from setuptools import setup\n')
#         f.write('from Cython.Build import cythonize\n')
#         f.write('setup(\n')
#         f.write("name='test',\n")
#         f.write("ext_modules=cythonize('%s')\n" % file_path)
#         f.write(")\n")
#     os.system('python setup.py build_ext --inplace')
#     filename = file_path.split('.py')[0]
#     time.sleep(2)
#     # 这里的cp37-win_amd64需要注意一下，这个是依据python解释器类型以及windows版本生成的，建议是单个生成一个pyd文件然后相应修改一下
#     os.rename('%s\\%s.cp38-win_64.pyd' % (folder_path, filename), '%s\\%s.pyd' % (folder_path, filename))
#     # 这个是删除py源文件，测试的时候可以先注释掉查看效果
#     os.remove('%s.c' % filename)
#     build_folder_path = os.path.join(folder_path, 'build')
#     # 删除掉生成的build文件夹
#     shutil.rmtree(build_folder_path)
#     os.remove('setup.py')
#     os.remove(file_path)


# def get_all_file(path):
#     for root, dirs, files in os.walk(path):
#         for name in files:
#             if name.endswith(".py"):
#                 file_path = os.path.join(root, name)
#                 func(file_path)


# paths = sys.argv[1]
# get_all_file(paths)
