/* BdfServer_Commands - Copyright (c) 2010-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.commands.sphere;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.BdfServerEditor;
import fr.exemole.bdfserver.api.EditSession;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.managers.PermissionManager;
import fr.exemole.bdfserver.api.roles.Role;
import fr.exemole.bdfserver.tools.instruction.AbstractBdfCommand;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.sphere.Redacteur;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;


/**
 *
 * @author Vincent Calame
 */
public class RedacteurRoleCommand extends AbstractBdfCommand {

    public final static String COMMANDNAME = "RedacteurRole";
    public final static String COMMANDKEY = "_ ROL-04";
    public final static String ADMIN_PARAMNAME = "admin";
    public final static String ROLE_PARAMNAME = "role";
    private Boolean isAdmin;
    private Redacteur redacteur;
    private Set<String> roleNameSet;

    public RedacteurRoleCommand(BdfServer bdfServer, RequestMap requestMap) {
        super(bdfServer, requestMap);
    }

    @Override
    public boolean needSynchronisation() {
        return true;
    }

    @Override
    protected void doCommand() throws ErrorMessageException {
        try (EditSession session = startEditSession(Domains.SPHERE, COMMANDNAME)) {
            BdfServerEditor bdfServerEditor = session.getBdfServerEditor();
            changeRoles(bdfServerEditor);
            if (isAdmin != null) {
                bdfServerEditor.setAdmin(redacteur.getGlobalId(), isAdmin);
            }
        }
        setDone("_ done.sphere.redacteurrole");
    }

    @Override
    protected void checkParameters() throws ErrorMessageException {
        checkFichothequeAdmin();
        PermissionManager permissionManager = bdfServer.getPermissionManager();
        redacteur = requestHandler.getMandatoryRedacteur();
        String status = redacteur.getStatus();
        boolean admin = requestHandler.isTrue(ADMIN_PARAMNAME);
        switch (status) {
            case FichothequeConstants.INACTIVE_STATUS:
            case FichothequeConstants.READONLY_STATUS:
                if (admin) {
                    throw BdfErrors.error("_ error.unsupported.notadminstatus", redacteur.getBracketStyle());
                }
        }
        boolean current = permissionManager.isAdmin(redacteur);
        if (current == admin) {
            isAdmin = null;
        } else {
            if (current) {
                if (bdfServer.getPermissionManager().getAdminRedacteurList().size() == 1) {
                    throw BdfErrors.error("_ error.unsupported.lastadmin", redacteur.getBracketStyle());
                }
            }
            isAdmin = admin;
        }
        roleNameSet = new HashSet<String>();
        for (String token : requestHandler.getTokens(ROLE_PARAMNAME)) {
            roleNameSet.add(token);
        }
    }

    private void changeRoles(BdfServerEditor bdfServerEditor) {
        PermissionManager permissionManager = bdfServer.getPermissionManager();
        List<Role> currentRoleList = permissionManager.getRoleList(redacteur);
        List<Role> removeList = new ArrayList<Role>();
        for (Role role : currentRoleList) {
            String name = role.getName();
            if (!roleNameSet.contains(name)) {
                removeList.add(role);
            }
        }
        for (Role role : removeList) {
            bdfServerEditor.unlink(redacteur.getGlobalId(), role);
        }
        for (String roleName : roleNameSet) {
            Role role = permissionManager.getRole(roleName);
            if (role != null) {
                bdfServerEditor.link(redacteur, role);
            }
        }
    }

}
