package com.agent.management.service;

import com.agent.management.model.common.CredentialHolder;
import lombok.RequiredArgsConstructor;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Component;

/**
 * 凭据加解密 + 脱敏工具（DataSource / GraphSource 共用）。
 *
 * <p>集中处理 Jasypt 加解密逻辑，消除两个 ServiceImpl 中的重复代码，
 * 同时通过 {@link CredentialHolder#getDecryptedPassword()} 字段隔离运行时明文，
 * 避免历史上"密文写回 passwordEnc 字段"造成的语义混淆。</p>
 */
@Component
@RequiredArgsConstructor
public class CredentialManager {

    private final StringEncryptor encryptor;

    /** 加密明文 → 返回 Jasypt 密文 */
    public String encrypt(String plain) {
        if (plain == null || plain.isEmpty()) {
            throw new IllegalArgumentException("密码不能为空");
        }
        return encryptor.encrypt(plain);
    }

    /** 解密 Jasypt 密文 → 返回明文 */
    public String decrypt(String enc) {
        if (enc == null || enc.isEmpty()) {
            throw new IllegalArgumentException("密文不能为空");
        }
        return encryptor.decrypt(enc);
    }

    /**
     * 把 passwordEnc 解密后写入 decryptedPassword 字段（不影响 passwordEnc）。
     *
     * <p>调用方（DataSource/GraphSource Service）在需要把实体传给下游执行器前调用，
     * 下游通过 {@code holder.getDecryptedPassword()} 取得明文。</p>
     */
    public void decryptToTransient(CredentialHolder holder) {
        if (holder == null) return;
        if (holder.getPasswordEnc() != null) {
            holder.setDecryptedPassword(encryptor.decrypt(holder.getPasswordEnc()));
        }
    }

    /**
     * 脱敏：清空所有密码相关字段，确保 Controller 返回的 DTO 不泄漏敏感信息。
     *
     * <p>无论 passwordEnc / passwordPlain / decryptedPassword 都置为 null。</p>
     */
    public void sanitize(CredentialHolder holder) {
        if (holder == null) return;
        holder.setPasswordEnc(null);
        holder.setPasswordPlain(null);
        holder.setDecryptedPassword(null);
    }
}
