"""
本模块的函数有一大部分都需要管理员权限! 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

author:Huang Yi yi

sion 模块提供了一系列与系统操作、文件处理、菜单管理等相关的功能。

该模块使用了requests和pywin32和mutagen和wmi和bs4和pyunpack和rarfile和py7zr和psutil和pefile模块,以及Python的标准库

使用示例1：
    from sion import attributes
    file_path = 'test.txt'
    result = attributes(file_path,True)#将文件设为隐藏
    print(result)

使用示例2：
    from sion import size
    width, height = size()#获取屏幕的宽和高

使用示例3：
    from sion import crawl_website
    start_url = "https://example.com"
    base_dir = "D:/test"
    crawl_website(start_url, base_dir)#爬取https://example.com网站,把其中的图片,js,css等都存到一个D:/test的目录里,相对路径也可以

使用示例4：
    from sion import FileCompressor
    # 要压缩的源文件或文件夹路径
    source = 'path/to/your/source'
    # 压缩文件的输出路径（不包含扩展名）
    output = 'path/to/your/output'

    with FileCompressor(source, output) as file:
        file.zip()#压缩成zip
        file.tar()#压缩成tar
        file.gz()#压缩成gz
        file.bz2()#压缩成bz2
        file.targz()#压缩成tar.gz
        file.tarbz2()#压缩成tar.bz2
        file.rar()#压缩成rar
            ...#当然也有解压缩,是FileDecompressor,同样支持with语句

使用示例5：
    from sion import exe, lnk#ExeIcon,LnkIcon是一样的
    with exe('path/to/your/exe.exe','path/to/your/icon.ico') as file:
        file.icon()#将指定的exe文件图标转为指定的路径的ico文件.

    with lnk('path/to/your/lnk.lnk','path/to/your/icon.ico') as file:
        file.icon()#将指定的lnk文件图标转为指定的路径的ico文件.

    #也有获取:get_icon
"""
import logging, ctypes
import win32com.client
import pythoncom


def _initialize_module():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    file_handler = logging.FileHandler('extexsion.log')
    file_handler.setLevel(logging.DEBUG)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)

    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)

    logger.addHandler(file_handler)
    logger.addHandler(console_handler)


FILE_ATTRIBUTE_HIDDEN = 0x2
FILE_ATTRIBUTE_READONLY = 0x1
FILE_ATTRIBUTE_ARCHIVE = 0x20
FILE_ATTRIBUTE_SYSTEM = 0x4
FILE_ATTRIBUTE_COMPRESSED = 0x800
APPCOMMAND_VOLUME_UP = 0xA0
APPCOMMAND_VOLUME_DOWN = 0x90
APPCOMMAND_VOLUME_MUTE = 0x80
WM_APPCOMMAND = 0x319
WM_USER = 0x0400
NIN_BALLOONSHOW = WM_USER + 2
NIN_BALLOONHIDE = WM_USER + 3
NIN_BALLOONTIMEOUT = WM_USER + 4
NIN_BALLOONUSERCLICK = WM_USER + 5
NIM_ADD = 0x00000000
NIM_MODIFY = 0x00000001
NIM_DELETE = 0x00000002
NIF_ICON = 0x00000002
NIF_MESSAGE = 0x00000001
_initialize_module()

#title
__title__ = "txsion"

#version
__version__ = '0.2.4'

#import ...
from .main import (
    attributes, right_rotate, sha256, filehash, open_url, download,
    system, username, increase, delete, modify, desktop, path, obtain,
    menu_app, add_menu, menu_icon, variable, Systemtime, association, systemkey,
    exvironment, SystemTime, read, read_file, shortcut, add_drivers,
    getregedit, afterdef, driver, winagent, winprohibt, create_process,
    delete_process, backend, split, dirname, copy, copy2, delete_file, filehash,
    ctrlc, curani, size, screenshot, brightness, battery_capacity, exit, quit, laptop,
    laptop_fan_strategy, screen_brightness,
)


try:
    from .main import notification

except ImportError as i:
    print(f"Error: {i}")


user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32
kernel32 = ctypes.windll.kernel32
winmm = ctypes.windll.winmm
gdiplus = ctypes.CDLL('gdiplus.dll')


from .main import (
    Path,
)

try:
    from .main import (
        MP3ID3, 
        error, 
        SendEmail,
        WinRightCilck,
        FileCompressor,
        FileDecompressor,
        WindowsVolumeController,
        ED2KDownloader,
        WinWiFi,
        ExeFile,
        extension,
        Taskbar,
        Window,
        CustomSystemExit,
    )

except ImportError as e:
    print('NO! ERROR:',e) 
    exit(1)

from .icon import ExeIcon, LnkIcon, BaseIcon

#Test
"""
width,height = size()
print(width,height)

with ExeIcon('D:/exe.exe','D:/icon.ico')as file:
    file.get_icon()
    file.icon()

with LnkIcon('D:/lnk.lnk','D:/icon.ico')as file:
    file.get_icon()
    file.icon()
"""

import platform

class Simple:
    def __init__(self, lib_path):
        self.lib_path = lib_path
        self.system = platform.system()
        self._load_library()

    def _load_library(self):
        """
        根据不同操作系统加载动态链接库
        """
        if self.system == 'Windows':
            if not self.lib_path.endswith('.dll'):
                self.lib_path += '.dll'
            try:
                self.lib = ctypes.CDLL(self.lib_path)
            except OSError as e:
                raise OSError(f"加载 Windows DLL 失败: {e}")
        elif self.system == 'Linux':
            if not self.lib_path.endswith('.so'):
                # 尝试查找系统库路径
                full_path = ctypes.util.find_library(self.lib_path)
                if full_path:
                    self.lib_path = full_path
                else:
                    self.lib_path += '.so'
            try:
                self.lib = ctypes.CDLL(self.lib_path)
            except OSError as e:
                raise OSError(f"加载 Linux SO 失败: {e}")
        elif self.system == 'Darwin':
            if not self.lib_path.endswith('.dylib'):
                self.lib_path += '.dylib'
            try:
                self.lib = ctypes.CDLL(self.lib_path)
            except OSError as e:
                raise OSError(f"加载 macOS DYLIB 失败: {e}")
        else:
            raise OSError(f"不支持的操作系统: {self.system}")

    def find_function(self, func_name):
        """
        在动态链接库中查找函数
        """
        try:
            func = getattr(self.lib, func_name)
            return func
        except AttributeError:
            raise AttributeError(f"在库 {self.lib_path} 中未找到函数 {func_name}")

    def call_function(self, func, argtypes, restype, *args):
        """
        调用函数，处理参数和返回值
        """
        func.argtypes = argtypes
        func.restype = restype
        try:
            return func(*args)
        except Exception as e:
            raise RuntimeError(f"调用函数 {func.__name__} 失败: {e}")
        

def lnk_target(lnk_path, target_path, arguments=""):
    """
    修改 .lnk 文件所指向的目标及参数
    :param lnk_path: .lnk 文件的路径
    :param target_path: 新的目标路径
    :param arguments: 目标程序的命令行参数，默认为空
    """
    # 初始化 COM 库
    pythoncom.CoInitialize()
    try:
        # 创建 ShellLink 对象
        shell = win32com.client.Dispatch("WScript.Shell")
        shortcut = shell.CreateShortCut(lnk_path)
        # 修改目标路径
        shortcut.TargetPath = target_path
        # 设置命令行参数
        shortcut.Arguments = arguments
        # 保存修改后的快捷方式
        shortcut.Save()
        if arguments:
            pass
        else:
            pass
    except Exception as e:
        print(f"修改快捷方式目标时出错: {e}")
    finally:
        # 释放 COM 库资源
        pythoncom.CoUninitialize()

import runcommand

def run(command, shell=None):
    """
    执行命令
    command:命令
    shell:是否用shell
    """
    system_name = system()
    if system_name == 'Windows':
        if shell is None:
            # 使用原有的 run 函数执行命令
            shell = "cmd.exe"
            code = runcommand.run(command, shell)
            return code
        elif shell.lower() == 'powershell':
            try:
                # 使用新增的 run_with_powershell 函数执行命令
                powershell_code = runcommand.run_with_powershell(command)
                return powershell_code
            except RuntimeError as e:
                print(f"Error: {e}")
                return None
        else:
            code = runcommand.run(command, shell)
            return code
    else:
        if shell is None:
            shell = "/bin/bash"
        code = runcommand.run(command, shell)
        return code


from _language import language
from notification import notification


lnk = LnkIcon
exe = ExeIcon
Icon = BaseIcon