package sgc.portal.security;

import sgc.portal.SgcPortalProperties;
import sgc.portal.base.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 기존 com.easyframework.security.service.PasswordEncryptionService 클래스 재구현.
 *
 * @author YongSang
 * @since 2019.10.14
 */
@Service
public class PasswordEncryptionService {

    @Autowired
    private SgcPortalProperties props;

    /**
     * Encrypt password with salt string.
     *
     * @param rawPassword the raw password
     * @return the string
     */
    public String encryptPasswordWithSalt(String rawPassword) {
        return encryptPasswordWithSalt(rawPassword, props.getSecurity().getSalt());
    }

    /**
     * Encrypt password with salt string.
     *
     * @param rawPassword the raw password
     * @param salt        the salt
     * @return the string
     */
    private String encryptPasswordWithSalt(String rawPassword, String salt) {
        if (StringUtils.isEmpty(rawPassword) || StringUtils.isEmpty(salt)) {
            throw new BusinessException("rawPassword or salt must be not null.");
        }
        return encrypt(rawPassword, salt.getBytes());
    }

    private String encrypt(String source, byte[] salt) {
        String result;
        byte[] a = source.getBytes();
        byte[] bytes = new byte[a.length + salt.length];
        System.arraycopy(a, 0, bytes, 0, a.length);
        System.arraycopy(salt, 0, bytes, a.length, salt.length);

        try {
            MessageDigest md = MessageDigest.getInstance(props.getSecurity().getVectorMessageForm());
            md.update(bytes);
            byte[] byteData = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte byteDatum : byteData) {
                sb.append(Integer.toString((byteDatum & 0xFF) + 256, 16).substring(1));
            }
            result = sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new BusinessException(e);
        }
        return result;
    }
}
