package top.tqx.demo_1.util;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * SHA256 哈希工具类
 * 支持文件和字符串的 SHA256 哈希计算
 */
public class Sha256Util {

    private static final String ALGORITHM = "SHA-256";
    private static final int BUFFER_SIZE = 8192;

    /**
     * 计算字符串的 SHA256 哈希值
     *
     * @param content 要哈希的字符串
     * @return SHA256 哈希值（64位十六进制字符串）
     */
    public static String hash(String content) {
        if (content == null) {
            return null;
        }
        try {
            MessageDigest digest = MessageDigest.getInstance(ALGORITHM);
            byte[] hashBytes = digest.digest(content.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hashBytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not available", e);
        }
    }

    /**
     * 计算 MultipartFile 的 SHA256 哈希值
     *
     * @param file MultipartFile 文件
     * @return SHA256 哈希值（64位十六进制字符串）
     */
    public static String hash(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return null;
        }
        try (InputStream is = file.getInputStream()) {
            return hash(is);
        } catch (IOException e) {
            throw new RuntimeException("Failed to calculate SHA-256 hash for file", e);
        }
    }

    /**
     * 计算 File 的 SHA256 哈希值
     *
     * @param file File 对象
     * @return SHA256 哈希值（64位十六进制字符串）
     */
    public static String hash(File file) {
        if (file == null || !file.exists()) {
            return null;
        }
        try (FileInputStream fis = new FileInputStream(file)) {
            return hash(fis);
        } catch (IOException e) {
            throw new RuntimeException("Failed to calculate SHA-256 hash for file", e);
        }
    }

    /**
     * 计算 InputStream 的 SHA256 哈希值
     *
     * @param inputStream 输入流
     * @return SHA256 哈希值（64位十六进制字符串）
     */
    public static String hash(InputStream inputStream) {
        if (inputStream == null) {
            return null;
        }
        try {
            MessageDigest digest = MessageDigest.getInstance(ALGORITHM);
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                digest.update(buffer, 0, bytesRead);
            }
            return bytesToHex(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not available", e);
        } catch (IOException e) {
            throw new RuntimeException("Failed to read input stream", e);
        }
    }

    /**
     * 计算字节数组的 SHA256 哈希值
     *
     * @param bytes 字节数组
     * @return SHA256 哈希值（64位十六进制字符串）
     */
    public static String hash(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            MessageDigest digest = MessageDigest.getInstance(ALGORITHM);
            return bytesToHex(digest.digest(bytes));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not available", e);
        }
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}
