<commit_before>/*
 * Wegas
 * http://wegas.albasim.ch
 *
 * Copyright (c) 2013-2018 School of Business and Engineering Vaud, Comem, MEI
 * Licensed under the MIT License
 */
package com.wegas.core.rest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wegas.core.Helper;
import com.wegas.core.ejb.GameFacade;
import com.wegas.core.ejb.GameModelCheck;
import com.wegas.core.ejb.GameModelFacade;
import com.wegas.core.ejb.RequestManager;
import com.wegas.core.ejb.VariableDescriptorFacade;
import com.wegas.core.ejb.statemachine.StateMachineFacade;
import com.wegas.core.exception.client.WegasErrorMessage;
import com.wegas.core.exception.client.WegasNotFoundException;
import com.wegas.core.exception.client.WegasScriptException;
import com.wegas.core.exception.internal.WegasNoResultException;
import com.wegas.core.i18n.persistence.TranslatableContent;
import com.wegas.core.persistence.game.*;
import com.wegas.core.persistence.variable.ListDescriptor;
import com.wegas.core.persistence.variable.ListInstance;
import com.wegas.core.persistence.variable.VariableDescriptor;
import com.wegas.core.persistence.variable.VariableInstance;
import com.wegas.core.persistence.variable.primitive.NumberDescriptor;
import com.wegas.core.persistence.variable.scope.GameModelScope;
import com.wegas.core.persistence.variable.statemachine.State;
import com.wegas.core.persistence.variable.statemachine.StateMachineDescriptor;
import com.wegas.core.persistence.variable.statemachine.Transition;
import com.wegas.core.rest.util.JacksonMapperProvider;
import com.wegas.core.rest.util.Views;
import com.wegas.mcq.persistence.ChoiceDescriptor;
import com.wegas.mcq.persistence.Result;
import com.wegas.resourceManagement.ejb.ResourceFacade;
import com.wegas.resourceManagement.persistence.Occupation;
import com.wegas.resourceManagement.persistence.ResourceDescriptor;
import com.wegas.resourceManagement.persistence.ResourceInstance;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author <NAME> (fx at red-agent.com)
 */
@Stateless
@Path("Update")
@RequiresRoles("Administrator")
public class UpdateController {

    private static Logger logger = LoggerFactory.getLogger(UpdateController.class);

    @EJB
    private VariableDescriptorFacade descriptorFacade;

    @EJB
    private VariableDescriptorController descriptorController;

    @EJB
    private GameModelFacade gameModelFacade;

    @Inject
    private GameFacade gameFacade;

    @Inject
    private ResourceFacade resourceFacade;

    @Inject
    private RequestManager requestManager;

    @Inject
    private StateMachineFacade stateMachineFacade;

    @Inject
    private ScriptController scriptController;

    @Inject
    private GameModelCheck gameModelCheck;

    /**
     * @return Some String encoded HTML
     */
    @GET
    public String index() {
        //Long nbOrphans = this.countOrphans();
        //List<Game> noDebugTeamGames = this.findNoDebugTeamGames();

        //ret.append("<a href=\"Update/KillOrphans\">Kill Ulvide and 3000 Orphans (" + nbOrphans + " orphans)</a> <br />");
        //ret.append("<a href=\"Update/RestoreDebugTeams\">Restore 25 Debug Teams and Kill Ulvide (" + noDebugTeamGames.size() + " games)</a> <br />");
        //ret.append("<a href=\"Update/PMG_UPGRADE\">PMG upgrade</a> <br />");
        // for (GameModel gm : gameModelFacade.findAll()) {
        //    ret.append("<a href=\"Encode/").append(gm.getId()).append("\">Update variable names ").append(gm.getId()).append("</a> | ");
        //    ret.append("<a href=\"UpdateScript/").append(gm.getId()).append("\">Update script ").append(gm.getId()).append("</a><br />");
        //}
        return "<a href=\"RtsUpdateScope/10901\">RTS Update Scopes</a> <br />"
                + "<a href=\"RtsNewScope/10901\">RTS New Scopes</a> <br />";
    }

    /**
     * Retrieve
     *
     * @param gameModelId
     *
     * @return static "Finished" string...
     */
    @GET
    @Path("Encode/{gameModelId : ([1-9][0-9]*)}")
    public String encode(@PathParam("gameModelId") Long gameModelId) {
        List<VariableDescriptor> findAll = descriptorFacade.findByGameModelId(gameModelId);
        for (VariableDescriptor vd : findAll) {
            List<String> findDistinctNames = descriptorFacade.findDistinctNames(vd.getGameModel(), vd.getRefId());
            List<TranslatableContent> findDistinctLabels = descriptorFacade.findDistinctLabels(vd.getGameModel());
            findDistinctNames.remove(vd.getName());
            findDistinctLabels.remove(vd.getLabel());
            Helper.setUniqueName(vd, findDistinctNames, vd.getGameModel());
            Helper.setUniqueLabel(vd, findDistinctLabels, vd.getGameModel());
            descriptorFacade.flush();
        }
        return "Finished";
    }

    /**
     * @param gameModelId
     *
     * @return static "Finished" string...
     */
    @GET
    @Path("UpdateScript/{gameModelId : ([1-9][0-9]*)}")
    public String script(@PathParam("gameModelId") Long gameModelId) {
        Collection<VariableDescriptor> findAll = descriptorFacade.findAll(gameModelId);
        List<String> keys = new ArrayList<>();
        List<String> values = new ArrayList<>();
        for (VariableDescriptor vd : findAll) {
            keys.add("VariableDescriptorFacade\\.find\\(" + vd.getId() + "\\)");
            values.add("VariableDescriptorFacade.find(gameModel, \"" + vd.getName() + "\")");
        }

        for (VariableDescriptor vd : findAll) {
            if (vd instanceof ChoiceDescriptor) {
                ChoiceDescriptor choice = (ChoiceDescriptor) vd;
                for (Result r : choice.getResults()) {
                    replaceAll(r.getImpact(), keys, values);
                }
            } else if (vd instanceof StateMachineDescriptor) {
                StateMachineDescriptor fsm = (StateMachineDescriptor) vd;
                for (Map.Entry<Long, State> s : fsm.getStatesAsMap().entrySet()) {
                    replaceAll(s.getValue().getOnEnterEvent(), keys, values);
                    for (Transition t : s.getValue().getTransitions()) {
                        replaceAll(t.getPreStateImpact(), keys, values);
                        replaceAll(t.getTriggerCondition(), keys, values);
                    }
                }
            }
        }
        return "Finished";
    }

    private static void replaceAll(Script script, List<String> a, List<String> b) {
        if (script == null) {
            return;
        }
        String s = script.getContent();
        for (int i = 0; i < a.size(); i++) {
            s = s.replaceAll(a.get(i), b.get(i));
        }
        script.setContent(s);
    }

    private List<GameModel> findPMGs(boolean scenarioOnly) {
        EntityManager em = this.getEntityManager();
        final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        final CriteriaQuery<GameModel> query = criteriaBuilder.createQuery(GameModel.class);

        Root<GameModel> e = query.from(GameModel.class);
        Predicate where;

        if (scenarioOnly) {
            where = criteriaBuilder.and(
                    criteriaBuilder.equal(e.get("type"), GameModel.GmType.SCENARIO),
                    criteriaBuilder.like(e.get("properties").get("clientScriptUri"), "wegas-private/wegas-pmg/js/wegas-pmg-loader.js;wegas-private/wegas-pmg/scripts/wegas-pmg-client.js")
            );
        } else {
            where = criteriaBuilder.like(e.get("properties").get("clientScriptUri"), "wegas-private/wegas-pmg/js/wegas-pmg-loader.js;wegas-private/wegas-pmg/scripts/wegas-pmg-client.js");
        }

        query.select(e)
                .where(where);

        return em.createQuery(query).getResultList();
    }

    private String updateHistorySize(GameModel aPmg) {
        StringBuilder sb = new StringBuilder("<ul><li><b>Update Histor Size for ");
        sb.append(aPmg).append("</b></li>");

        String[] varNames = {
            "managementApproval",
            "userApproval",
            "quality",
            "costs",
            "delay",
            "planedValue",
            "earnedValue",
            "actualCost"
        };

        int nothing = 0;

        for (String varName : varNames) {
            sb.append("<li>").append(varName);
            try {
                NumberDescriptor nd = (NumberDescriptor) descriptorFacade.find(aPmg, varName);
                if (nd.getHistorySize() != null) {
                    sb.append("  updated");
                    nd.setHistorySize(null);
                } else {
                    sb.append("  nothing to do");
                    nothing++;
                }
            } catch (WegasNoResultException ex) {
                sb.append("  not found");
                java.util.logging.Logger.getLogger(UpdateController.class.getName()).log(Level.SEVERE, null, ex);
            }
            sb.append("</li>");
        }
        sb.append("</ul>");
        if (nothing == varNames.length) {
            return "<ul><li>" + aPmg + "OK</li></ul>";
        } else {
            return sb.toString();
        }
    }

    private void updateScope(VariableDescriptor vd) {
        if (!(vd.getScope() instanceof GameModelScope)) {
            EntityManager em = this.getEntityManager();

            Collection<VariableInstance> values = this.descriptorFacade.getInstances(vd).values();

            for (VariableInstance vi : values) {
                em.remove(vi);
            }
            GameModelScope scope = new GameModelScope();
            scope.setBroadcastScope("GameScope");
            scope.setVariableDescscriptor(vd);
            vd.setScope(scope);
            em.persist(vd);
            vd.propagateDefaultInstance(null, true);
        }
    }

    private String updateListDescriptorScope(GameModel gameModel) {
        Collection<VariableDescriptor> variableDescriptors = gameModel.getVariableDescriptors();
        StringBuilder sb = new StringBuilder();
        sb.append("[");

        for (VariableDescriptor vd : variableDescriptors) {
            if (vd instanceof ListDescriptor) {<commit_msg>Fix "change descriptor scope"<commit_after>/*
 * Wegas
 * http://wegas.albasim.ch
 *
 * Copyright (c) 2013-2018 School of Business and Engineering Vaud, Comem, MEI
 * Licensed under the MIT License
 */
package com.wegas.core.rest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wegas.core.Helper;
import com.wegas.core.ejb.GameFacade;
import com.wegas.core.ejb.GameModelCheck;
import com.wegas.core.ejb.GameModelFacade;
import com.wegas.core.ejb.RequestManager;
import com.wegas.core.ejb.VariableDescriptorFacade;
import com.wegas.core.ejb.statemachine.StateMachineFacade;
import com.wegas.core.exception.client.WegasErrorMessage;
import com.wegas.core.exception.client.WegasNotFoundException;
import com.wegas.core.exception.client.WegasScriptException;
import com.wegas.core.exception.internal.WegasNoResultException;
import com.wegas.core.i18n.persistence.TranslatableContent;
import com.wegas.core.persistence.game.*;
import com.wegas.core.persistence.variable.ListDescriptor;
import com.wegas.core.persistence.variable.ListInstance;
import com.wegas.core.persistence.variable.VariableDescriptor;
import com.wegas.core.persistence.variable.VariableInstance;
import com.wegas.core.persistence.variable.primitive.NumberDescriptor;
import com.wegas.core.persistence.variable.scope.AbstractScope;
import com.wegas.core.persistence.variable.scope.GameModelScope;
import com.wegas.core.persistence.variable.statemachine.State;
import com.wegas.core.persistence.variable.statemachine.StateMachineDescriptor;
import com.wegas.core.persistence.variable.statemachine.Transition;
import com.wegas.core.rest.util.JacksonMapperProvider;
import com.wegas.core.rest.util.Views;
import com.wegas.mcq.persistence.ChoiceDescriptor;
import com.wegas.mcq.persistence.Result;
import com.wegas.resourceManagement.ejb.ResourceFacade;
import com.wegas.resourceManagement.persistence.Occupation;
import com.wegas.resourceManagement.persistence.ResourceDescriptor;
import com.wegas.resourceManagement.persistence.ResourceInstance;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author <NAME> (fx at red-agent.com)
 */
@Stateless
@Path("Update")
@RequiresRoles("Administrator")
public class UpdateController {

    private static Logger logger = LoggerFactory.getLogger(UpdateController.class);

    @EJB
    private VariableDescriptorFacade descriptorFacade;

    @EJB
    private VariableDescriptorController descriptorController;

    @EJB
    private GameModelFacade gameModelFacade;

    @Inject
    private GameFacade gameFacade;

    @Inject
    private ResourceFacade resourceFacade;

    @Inject
    private RequestManager requestManager;

    @Inject
    private StateMachineFacade stateMachineFacade;

    @Inject
    private ScriptController scriptController;

    @Inject
    private GameModelCheck gameModelCheck;

    /**
     * @return Some String encoded HTML
     */
    @GET
    public String index() {
        //Long nbOrphans = this.countOrphans();
        //List<Game> noDebugTeamGames = this.findNoDebugTeamGames();

        //ret.append("<a href=\"Update/KillOrphans\">Kill Ulvide and 3000 Orphans (" + nbOrphans + " orphans)</a> <br />");
        //ret.append("<a href=\"Update/RestoreDebugTeams\">Restore 25 Debug Teams and Kill Ulvide (" + noDebugTeamGames.size() + " games)</a> <br />");
        //ret.append("<a href=\"Update/PMG_UPGRADE\">PMG upgrade</a> <br />");
        // for (GameModel gm : gameModelFacade.findAll()) {
        //    ret.append("<a href=\"Encode/").append(gm.getId()).append("\">Update variable names ").append(gm.getId()).append("</a> | ");
        //    ret.append("<a href=\"UpdateScript/").append(gm.getId()).append("\">Update script ").append(gm.getId()).append("</a><br />");
        //}
        return "<a href=\"RtsUpdateScope/10901\">RTS Update Scopes</a> <br />"
                + "<a href=\"RtsNewScope/10901\">RTS New Scopes</a> <br />";
    }

    /**
     * Retrieve
     *
     * @param gameModelId
     *
     * @return static "Finished" string...
     */
    @GET
    @Path("Encode/{gameModelId : ([1-9][0-9]*)}")
    public String encode(@PathParam("gameModelId") Long gameModelId) {
        List<VariableDescriptor> findAll = descriptorFacade.findByGameModelId(gameModelId);
        for (VariableDescriptor vd : findAll) {
            List<String> findDistinctNames = descriptorFacade.findDistinctNames(vd.getGameModel(), vd.getRefId());
            List<TranslatableContent> findDistinctLabels = descriptorFacade.findDistinctLabels(vd.getGameModel());
            findDistinctNames.remove(vd.getName());
            findDistinctLabels.remove(vd.getLabel());
            Helper.setUniqueName(vd, findDistinctNames, vd.getGameModel());
            Helper.setUniqueLabel(vd, findDistinctLabels, vd.getGameModel());
            descriptorFacade.flush();
        }
        return "Finished";
    }

    /**
     * @param gameModelId
     *
     * @return static "Finished" string...
     */
    @GET
    @Path("UpdateScript/{gameModelId : ([1-9][0-9]*)}")
    public String script(@PathParam("gameModelId") Long gameModelId) {
        Collection<VariableDescriptor> findAll = descriptorFacade.findAll(gameModelId);
        List<String> keys = new ArrayList<>();
        List<String> values = new ArrayList<>();
        for (VariableDescriptor vd : findAll) {
            keys.add("VariableDescriptorFacade\\.find\\(" + vd.getId() + "\\)");
            values.add("VariableDescriptorFacade.find(gameModel, \"" + vd.getName() + "\")");
        }

        for (VariableDescriptor vd : findAll) {
            if (vd instanceof ChoiceDescriptor) {
                ChoiceDescriptor choice = (ChoiceDescriptor) vd;
                for (Result r : choice.getResults()) {
                    replaceAll(r.getImpact(), keys, values);
                }
            } else if (vd instanceof StateMachineDescriptor) {
                StateMachineDescriptor fsm = (StateMachineDescriptor) vd;
                for (Map.Entry<Long, State> s : fsm.getStatesAsMap().entrySet()) {
                    replaceAll(s.getValue().getOnEnterEvent(), keys, values);
                    for (Transition t : s.getValue().getTransitions()) {
                        replaceAll(t.getPreStateImpact(), keys, values);
                        replaceAll(t.getTriggerCondition(), keys, values);
                    }
                }
            }
        }
        return "Finished";
    }

    private static void replaceAll(Script script, List<String> a, List<String> b) {
        if (script == null) {
            return;
        }
        String s = script.getContent();
        for (int i = 0; i < a.size(); i++) {
            s = s.replaceAll(a.get(i), b.get(i));
        }
        script.setContent(s);
    }

    private List<GameModel> findPMGs(boolean scenarioOnly) {
        EntityManager em = this.getEntityManager();
        final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        final CriteriaQuery<GameModel> query = criteriaBuilder.createQuery(GameModel.class);

        Root<GameModel> e = query.from(GameModel.class);
        Predicate where;

        if (scenarioOnly) {
            where = criteriaBuilder.and(
                    criteriaBuilder.equal(e.get("type"), GameModel.GmType.SCENARIO),
                    criteriaBuilder.like(e.get("properties").get("clientScriptUri"), "wegas-private/wegas-pmg/js/wegas-pmg-loader.js;wegas-private/wegas-pmg/scripts/wegas-pmg-client.js")
            );
        } else {
            where = criteriaBuilder.like(e.get("properties").get("clientScriptUri"), "wegas-private/wegas-pmg/js/wegas-pmg-loader.js;wegas-private/wegas-pmg/scripts/wegas-pmg-client.js");
        }

        query.select(e)
                .where(where);

        return em.createQuery(query).getResultList();
    }

    private String updateHistorySize(GameModel aPmg) {
        StringBuilder sb = new StringBuilder("<ul><li><b>Update Histor Size for ");
        sb.append(aPmg).append("</b></li>");

        String[] varNames = {
            "managementApproval",
            "userApproval",
            "quality",
            "costs",
            "delay",
            "planedValue",
            "earnedValue",
            "actualCost"
        };

        int nothing = 0;

        for (String varName : varNames) {
            sb.append("<li>").append(varName);
            try {
                NumberDescriptor nd = (NumberDescriptor) descriptorFacade.find(aPmg, varName);
                if (nd.getHistorySize() != null) {
                    sb.append("  updated");
                    nd.setHistorySize(null);
                } else {
                    sb.append("  nothing to do");
                    nothing++;
                }
            } catch (WegasNoResultException ex) {
                sb.append("  not found");
                java.util.logging.Logger.getLogger(UpdateController.class.getName()).log(Level.SEVERE, null, ex);
            }
            sb.append("</li>");
        }
        sb.append("</ul>");
        if (nothing == varNames.length) {
            return "<ul><li>" + aPmg + "OK</li></ul>";
        } else {
            return sb.toString();
        }
    }

    private void updateScope(VariableDescriptor vd) {
        if (!(vd.getScope() instanceof GameModelScope)) {
            EntityManager em = this.getEntityManager();

            Collection<VariableInstance> values = this.descriptorFacade.getInstances(vd).values();

            for (VariableInstance vi : values) {
                em.remove(vi);
            }
            AbstractScope oldScope = vd.getScope();

            GameModelScope scope = new GameModelScope();
            scope.setBroadcastScope("GameScope");
            scope.setVariableDescscriptor(vd);
            vd.setScope(scope);
            em.persist(vd);
            vd.propagateDefaultInstance(null, true);
            em.remove(oldScope);
        }
    }

    private String updateListDescriptorScope(GameModel gameModel) {
        Collection<VariableDescriptor> variableDescriptors = gameModel.getVariableDescriptors();
        StringBuilder sb = new StringBuilder();
        sb.append("[");

        for (VariableDescriptor vd : variableDescriptors) {
            if (vd instanceof ListDescriptor) {
{'fraction_non_alphanumeric': 0.12753888380603842, 'fraction_numerical': 0.0034766697163769443, 'mean_word_length': 2.752317198764161, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5563720', 'n_tokens_mistral': 6391, 'n_tokens_neox': 6268, 'n_words': 1109}