/*
 * Wegas
 * http://wegas.albasim.ch
 *
 * Copyright (c) 2013-2020 School of Business and Engineering Vaud, Comem, MEI
 * Licensed under the MIT License
 */

package com.wegas.core.security.persistence.token;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.wegas.core.ejb.VariableDescriptorFacade;
import com.wegas.core.persistence.game.GameModel;
import com.wegas.core.persistence.variable.Beanjection;
import com.wegas.core.persistence.variable.VariableDescriptor;
import com.wegas.core.security.ejb.AccountFacade;
import com.wegas.core.security.util.WegasMembership;
import com.wegas.core.security.util.WegasPermission;
import com.wegas.survey.persistence.SurveyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author maxence
 */
@Entity
public class SurveyToken extends Token {

    @ManyToMany(mappedBy = "tokens")
    //@JsonView(Views.ExtendedI.class)
    @JsonIgnore
    private List<SurveyDescriptor> surveys;

    /**
     * Return the gameModel which define all the surveys. By design, a token can references several
     * surveys, but all surveys must belong to the same gameModel.
     *
     * @return the gameModel which contains surveys or null if there is no survey or if surveys
     *         belong to difference gameModel
     */
    public static GameModel getUniqueGameModel(List<SurveyDescriptor> surveys) {
        GameModel gm = null;
        for (SurveyDescriptor sd : surveys) {
            if (gm == null) {
                gm = sd.getGameModel();
            } else if (!gm.equals(sd.getGameModel())) {
                return null;
            }
        }
        return gm;
    }

    @JsonIgnore
    public GameModel getGameModel() {
        return SurveyToken.getUniqueGameModel(surveys);
    }

    public List<SurveyDescriptor> getSurveys() {
        return surveys;
    }

    public void setSurveys(List<SurveyDescriptor> surveys) {
        this.surveys = new ArrayList<>();
        for (SurveyDescriptor survey : surveys) {
            survey.getTokens().add(this);
            this.surveys.add(survey);
        }
    }

    @Override
    public String getRedirectTo() {
        List<String> ids = new ArrayList<>(surveys.size());
        for (SurveyDescriptor sd : this.getSurveys()) {
            ids.add(sd.getId().toString());
        }

        return "/survey.html?surveyIds=" + String.join(",", ids);
    }

    public void process(AccountFacade accountFacade, HttpServletRequest request) {
        accountFacade.processSurveyToken(this, request);
    }

    @Override
    public Collection<WegasPermission> getRequieredCreatePermission() {
        GameModel gm = SurveyToken.getUniqueGameModel(surveys);

        // can create only if the token is linked to one and only one gameModel
        if (gm != null) {
            return gm.getRequieredUpdatePermission();
        } else {
            return WegasMembership.FORBIDDEN;
        }
    }

    public void removeSurvey(SurveyDescriptor sd) {
        this.surveys.remove(sd);
    }

    @Override
    public void updateCacheOnDelete(Beanjection beans) {
        if (this.surveys != null) {
            VariableDescriptorFacade vdf = beans.getVariableDescriptorFacade();
            for (SurveyDescriptor sd : surveys) {
                VariableDescriptor find = vdf.find(sd.getId());
                if (find instanceof SurveyDescriptor) {
                    SurveyDescriptor sdf = (SurveyDescriptor) find;
                    sdf.removeToken(this);
                }
            }
        }

        super.updateCacheOnDelete(beans);
    }
}

@@ -520,32 +520,92 @@
 .AccountFacade;%0A
+import com.wegas.core.security.persistence.AbstractAccount;%0A
 import com.wegas
@@ -3126,32 +3126,608 @@
        %7D%0A    %7D%0A%0A
+    @Override%0A    public Collection%3CWegasPermission%3E getRequieredUpdatePermission() %7B%0A        Collection%3CWegasPermission%3E ps = new ArrayList%3C%3E();%0A%0A        GameModel gm = SurveyToken.getUniqueGameModel(surveys);%0A%0A        if (gm != null) %7B%0A            ps.addAll(gm.getRequieredUpdatePermission());%0A        %7D%0A%0A        AbstractAccount account = this.getAccount();%0A%0A        if (account != null) %7B%0A            ps.addAll(account.getRequieredUpdatePermission());%0A        %7D%0A%0A        if (ps.isEmpty())%7B%0A            ps.addAll(WegasMembership.ADMIN);%0A        %7D%0A%0A        return ps;%0A    %7D%0A%0A
     public void 

Allow trainer to read/write its tokens