/*-
 * ~~~~~~licensing~~~~~~
 * htpasswd
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.esb.system.auth.basic.htpasswd.entity;

import org.apache.commons.codec.binary.Base64;
import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm;

import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;

public class HtpasswdEntry {

    private static final String APR1_PREFIX = "$apr1$";
    private static final String SHA512_PREFIX = "$6$";
    private static final String SALTED_SHA1_PREFIX = "{SSHA}";
    private static final String PLAIN_PREFIX = "{PLAIN}";

    private static final String COLON = ":";
    private final String resultLine;

    public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm) throws NoSuchAlgorithmException {
        this(login, passwordHash, salt, encryptionAlgorithm, true);
    }

    public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm, boolean addLineSeparator) throws NoSuchAlgorithmException {
        StringBuilder content = new StringBuilder();
        content.append(login).append(COLON);

        if (EncryptionAlgorithm.MD5.equalsName(encryptionAlgorithm)) {
            content
                    .append(APR1_PREFIX)
                    .append(salt)
                    .append("$")
                    .append(passwordHash);
        } else if (EncryptionAlgorithm.SHA1.equalsName(encryptionAlgorithm)) {
            content.append(SALTED_SHA1_PREFIX);
            byte[] digest = Base64.decodeBase64(passwordHash);
            byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8);

            int l1 = digest.length;
            int l2 = saltBytes.length;
            byte[] resultArr = new byte[l1 + l2];
            System.arraycopy(digest, 0, resultArr, 0, l1);
            System.arraycopy(saltBytes, 0, resultArr, l1, l2);

            content.append(Base64.encodeBase64String(resultArr));
        } else if (EncryptionAlgorithm.SHA512.equalsName(encryptionAlgorithm)) {
            content
                    .append(SHA512_PREFIX)
                    .append(salt)
                    .append("$")
                    .append(passwordHash);
        } else if (EncryptionAlgorithm.PLAIN.equalsName(encryptionAlgorithm)) {
            content
                    .append(PLAIN_PREFIX)
                    .append(passwordHash);
        } else {
            content.append(passwordHash);
        }
        content.append(System.lineSeparator());

        this.resultLine = content.toString();
    }

    @Override
    public String toString() {
        return resultLine;
    }
}
