/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-legacy-auth
 * ==========
 * 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.platform.runtime.security.jaas.modules.entaxylegacy;

import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.karaf.jaas.boot.principal.GroupPrincipal;
import org.apache.karaf.jaas.boot.principal.RolePrincipal;
import org.apache.karaf.jaas.boot.principal.UserPrincipal;
import org.apache.karaf.jaas.modules.BackingEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService;
import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount;
import ru.entaxy.esb.system.auth.basic.jpa.api.exception.BadPasswordException;
import ru.entaxy.platform.base.support.CommonUtils;

public class EntaxyLegacyBackingEngine implements BackingEngine {

    private static final Logger log = LoggerFactory.getLogger(EntaxyLegacyBackingEngine.class);

    public static EntaxyLegacyBackingEngine INSTANCE = new EntaxyLegacyBackingEngine();

    public static final String SYSTEM_ROLE_PREFIX = "PROFILE_";

    @Override
    public void addUser(String username, String password) {
        if (ServiceHolder.getInstance() == null)
            return;
        try {
            ServiceHolder.getInstance().getBasicAuthService().saveCommon(username, password, null, "admin", "admin");
        } catch (NoSuchAlgorithmException | BadPasswordException e) {
            log.error("Error adding user: [" + username + "]", e);
        }
    }

    @Override
    public void deleteUser(String username) {
        if (ServiceHolder.getInstance() == null)
            return;
        ServiceHolder.getInstance().getBasicAuthService().remove(username);
    }

    @Override
    public List<UserPrincipal> listUsers() {
        if (ServiceHolder.getInstance() == null)
            return new ArrayList<>();

        return ServiceHolder.getInstance().getBasicAuthService().list().stream()
                .map(acc -> new UserPrincipal(acc.getLogin())).collect(Collectors.toList());
    }

    @Override
    public UserPrincipal lookupUser(String username) {
        if (ServiceHolder.getInstance() == null)
            return null;
        Optional<BasicAuthAccount> opt = getBasicAuthService().get(username);
        if (opt.isPresent())
            return new UserPrincipal(opt.get().getLogin());
        return null;
    }

    @Override
    public List<GroupPrincipal> listGroups(UserPrincipal user) {
        // NOT SUPPORTED
        return Collections.emptyList();
    }

    @Override
    public Map<GroupPrincipal, String> listGroups() {
        // NOT SUPPORTED
        return Collections.emptyMap();
    }

    @Override
    public void addGroup(String username, String group) {
        // NOT SUPPORTED
    }

    @Override
    public void createGroup(String group) {
        // NOT SUPPORTED
    }

    @Override
    public void deleteGroup(String username, String group) {
        // NOT SUPPORTED
    }

    @Override
    public List<RolePrincipal> listRoles(Principal principal) {
        if (ServiceHolder.getInstance() == null)
            return Collections.emptyList();
        if (principal instanceof UserPrincipal) {
            Optional<BasicAuthAccount> opt = getBasicAuthService().get(principal.getName());
            if (opt.isPresent()) {
                String systemUuid = opt.get().getSystemUUID();
                if (CommonUtils.isValid(systemUuid))
                    return Collections.singletonList(new RolePrincipal(SYSTEM_ROLE_PREFIX + systemUuid));
            }
        }
        return Collections.emptyList();
    }

    @Override
    public void addRole(String username, String role) {
        if (ServiceHolder.getInstance() == null)
            return;
        if (!CommonUtils.isValid(role))
            return;
        if (!role.startsWith(SYSTEM_ROLE_PREFIX))
            return;
        String systemUuid = role.substring(SYSTEM_ROLE_PREFIX.length());
        Optional<BasicAuthAccount> opt = getBasicAuthService().get(username);
        if (opt.isEmpty())
            return;
        opt.get().setSystemUUID(systemUuid);
        getBasicAuthService().save(opt.get(), true);
    }

    @Override
    public void deleteRole(String username, String role) {
        if (ServiceHolder.getInstance() == null)
            return;
        if (!CommonUtils.isValid(role))
            return;
        if (!role.startsWith(SYSTEM_ROLE_PREFIX))
            return;
        Optional<BasicAuthAccount> opt = getBasicAuthService().get(username);
        if (opt.isEmpty())
            return;
        opt.get().setSystemUUID(null);
        getBasicAuthService().save(opt.get(), true);
    }

    @Override
    public void addGroupRole(String group, String role) {
        // NOT SUPPORTED

    }

    @Override
    public void deleteGroupRole(String group, String role) {
        // NOT SUPPORTED

    }

    protected BasicAuthService getBasicAuthService() {
        return ServiceHolder.getInstance().getBasicAuthService();
    }

}
