#mysql
#pip install mysql-connector-python
import pexpect
import shlex
import re
import mysql.connector
from mysql.connector import Error
from tools.ToolBase import ToolBase

class MysqlTool(ToolBase):

    def test_empty_password_mysql_connection(self,host, username='root'):
        """
        测试使用空密码连接到指定 MySQL 服务器。

        参数:
            host (str): MySQL 服务器的主机地址,例如 'haitutech.cn'
            username (str): MySQL 用户名,默认值为 'root'
        """
        try:
            # 尝试使用空密码连接 MySQL
            connection = mysql.connector.connect(
                host=host,  # 主机地址
                user=username,  # 用户名
                password='',  # 空密码
                connection_timeout=10  # 设置10秒连接超时
            )
            if connection.is_connected():
                res = f"成功连接到 {host},用户 {username} 使用空密码"
                connection.close()  # 关闭连接以释放资源
        except Error as e:
            # 捕获并打印连接错误
            res = f"连接失败: {host} - {e}"
        return res

    def extract_mysql_password(self,command_line: str) -> str:
        """
        从 MySQL 命令行中提取 -p 参数后的密码值

        支持场景:
        -p''          → 返回空字符串
        -p'password'  → 返回 'password'
        -p"password"  → 返回 'password'
        -ppassword    → 返回 'password'
        -p password   → 返回 'password'
        """
        # 正则匹配模式
        pattern = r'''
            -p                  # 匹配 -p 参数
            (?:                 # 非捕获分组
                \s*             # 允许空格(如 -p password)
                (["']?)         # 捕获引号类型(单引号/双引号/无引号)
                (.*?)           # 捕获密码内容
                \1              # 闭合引号(与开头引号一致)
                |               # 或
                (\S+)           # 直接捕获无空格的密码(如 -ppassword)
            )
        '''
        matches = re.search(pattern, command_line, re.VERBOSE)

        if not matches:
            return ""

        # 提取密码(处理三种情况:引号包裹、无引号、直接拼接)
        password = matches.group(2) or matches.group(3) or ""
        return password

    def validate_instruction(self, instruction):
        timeout = 60
        #modified_code = "mysql空密码登录测试"
        instr = instruction.replace("--ssl-mode=DISABLED","--ssl=0")    #mariaDB 没有ssl-mode参数
        # if "--ssl=0" not in instr:
        #     instr = instr + " --ssl=0"
        return instr,timeout

    def do_worker_pexpect(self,str_instruction,timeout,ext_params):
        try:
            #safe_command = shlex.quote(str_instruction)
            #cmd = f"bash -c {safe_command}"
            strpwsd = self.extract_mysql_password(str_instruction)

            result = ""
            exc_do = pexpect.spawn('bash',['-c',str_instruction],timeout=timeout,encoding='utf-8')#spawn 第一个参数是可执行文件
            index = exc_do.expect([
                pexpect.TIMEOUT,
                pexpect.EOF,
                'Enter password:'
            ])
            result += str(exc_do.before)
            if index == 0 or index ==1:
                return result
            elif index==2:#针对要输入密码的情况,暂时智能输入个空字符
                result += "Enter password:\n"
                exc_do.sendline(strpwsd)  # 输入空密码后不知道会有多少种情况,密码不对,密码对
                index = exc_do.expect([pexpect.TIMEOUT, pexpect.EOF])
                result += str(exc_do.before)
            else:
                print("遇到其他输出!")
            return result
        except Exception as e:
            return f"执行错误: {str(e)}"

    #对于非sh命令调用的工具,自己实现命令执行的内容 --#2025-3-24暂时不使用
    def execute_instruction(self, instruction_old):
        ext_params = self.create_extparams()
        # 第一步:验证指令合法性
        instruction, timeout = self.validate_instruction(instruction_old)
        if not instruction:
            ext_params.is_user = True
            return False, instruction_old, "该指令暂不执行!由用户确认是否要兼容支持", "", ext_params  # 未
        # 过滤修改后的指令是否需要判重?同样指令再执行结果一致?待定---#?

        # 第二步:执行指令
        output = self.do_worker_pexpect(instruction, timeout, ext_params)

        # 第三步:分析执行结果
        if isinstance(output, bytes):  # 若是bytes则转成str
            output = output.decode('utf-8', errors='ignore')

        analysis = self.analyze_result(output, instruction, "", "")

        if not analysis:  # analysis为“” 不提交LLM
            ext_params.is_user = True
            return False, instruction, analysis, output, ext_params
        return True, instruction, analysis, output, ext_params

    def analyze_result(self, result,instruction,stderr,stdout):
        #如果有--------,把这些-去除掉
        if result:
            result = result.replace("--------------","")
        else:
            result = ""
        return result