package ebpftracer

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
	"unicode"
)

func GetJvmVersion(filePath string) (string, error) {
	minLength := 4
	var maxFileSize int64 = 3 * 1024 * 1024 // 3MB
	// 打开文件
	sofile, err := os.Open(filePath)
	if err != nil {
		return "", fmt.Errorf("failed to open file: %w", err)
	}
	defer sofile.Close()

	// 检查文件大小
	fileInfo, err := sofile.Stat()
	if err != nil {
		return "", fmt.Errorf("failed to stat file: %w", err)
	}
	if fileInfo.Size() > maxFileSize {
		return "", fmt.Errorf("file size exceeds limit of %d bytes", maxFileSize)
	}

	var result []string
	var buffer []rune

	// 逐字节读取文件
	buf := make([]byte, 4096) // 4KB 缓冲区
	for {
		n, err := sofile.Read(buf)
		if n > 0 {
			for _, b := range buf[:n] {
				// 检查是否是可打印字符
				if unicode.IsPrint(rune(b)) {
					buffer = append(buffer, rune(b))
				} else if len(buffer) >= minLength {
					// 如果当前缓冲区长度满足要求，则存入结果
					result = append(result, string(buffer))
					buffer = nil
				} else {
					// 清空缓冲区
					buffer = nil
				}
			}
		}
		if err != nil {
			if err.Error() != "EOF" {
				return "", fmt.Errorf("failed to read file: %w", err)
			}
			break
		}
	}

	// 如果缓冲区有剩余字符串，添加到结果中
	if len(buffer) >= minLength {
		result = append(result, string(buffer))
	}

	// 查找 `java.version` 的下一行
	keyword := "java.version"

	for i, str := range result {
		if str == keyword && i+1 < len(result) {
			return result[i+1], nil // 返回关键字下一行内容
		}
	}

	return "", fmt.Errorf("failed to extract java version from %s", filePath)
}

// 解析版本号为大版本、中间版本和小版本
func ParseVersion(version string) (int, int, int, error) {
	re := regexp.MustCompile(`^(\d+)\.(\d+)\.(\d+)`)
	matches := re.FindStringSubmatch(version)
	if len(matches) != 4 {
		return 0, 0, 0, fmt.Errorf("invalid version format")
	}

	major, _ := strconv.Atoi(matches[1])
	minor, _ := strconv.Atoi(matches[2])
	patch, _ := strconv.Atoi(matches[3])

	return major, minor, patch, nil
}

func parseQuotedString(input string) (string, error) {
	// 找到第一个双引号的位置
	start := strings.Index(input, "\"")
	if start == -1 {
		return "", fmt.Errorf("no start quote found")
	}

	// 找到第二个双引号的位置
	end := strings.Index(input[start+1:], "\"")
	if end == -1 {
		return "", fmt.Errorf("no end quote found")
	}

	// 提取开始和结束引号之间的内容
	content := input[start+1 : start+1+end]
	return content, nil
}

// getExecutablePath 根据进程ID获取可执行文件的真实路径。
func getExecutablePath(pid uint32) (string, error) {
	// 构造文件路径
	link := fmt.Sprintf("/proc/%d/exe", pid)

	// 使用os.Readlink获取符号链接指向的路径
	execPath, err := os.Readlink(link)
	if err != nil {
		return "", err
	}
	return execPath, nil
}

func UsePIDToGetJDKVersion(pid uint32) string {
	execPath, err := getExecutablePath(pid)
	if err != nil {
		fmt.Println("Error:", err)
		return ""
	}
	// 构建Command对象
	cmd := exec.Command(execPath, "-version")

	// 创建缓冲区保存输出
	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr // java -version 实际是写入Stderr

	// 运行命令
	err = cmd.Run()
	if err != nil {
		fmt.Println("Command execution error:", err)
		fmt.Println("Error output:", stderr.String())
		return ""
	}

	// 打印输出信息
	version, err := parseQuotedString(stderr.String())
	if err != nil {
		fmt.Println("Error:", err)
		return ""
	}
	return version

}
