/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
 *
 * ludovic.apvrille AT enst.fr
 *
 * This software is a computer program whose purpose is to allow the
 * edition of TURTLE analysis, design and deployment diagrams, to
 * allow the generation of RT-LOTOS or Java code from this diagram,
 * and at last to allow the analysis of formal validation traces
 * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
 * from INRIA Rhone-Alpes.
 *
 * This software is governed by the CeCILL  license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 */

package tmltranslator.mutations;

import avatartranslator.mutation.MutationParser;
import tmltranslator.TMLModeling;
import tmltranslator.TMLRequest;
import tmltranslator.TMLTask;
import tmltranslator.TMLType;

import java.util.LinkedList;
import java.util.List;

public class AddRequestConnectionMutation extends RequestConnectionMutation {
    protected List<String> parameters;

    protected AddRequestConnectionMutation(String _originTaskName, String _destinationTaskName, String _connectionName) {
        super(_originTaskName, _destinationTaskName, _connectionName);
    }

    public TMLRequest createElement(TMLModeling<?> _tmlModel) throws ApplyDiplodocusMutationException {
        if (getRequest(_tmlModel) != null){
            throw new ApplyDiplodocusMutationException("An request connection named " + getConnectionName() + " already exists in the current model.");
        }

        TMLRequest request = new TMLRequest(getConnectionName(), null);

        TMLTask _originTask = getOriginTask(_tmlModel);
        TMLTask _destinationTask = getDestinationTask(_tmlModel);
        if (_originTask == null){
            throw new ApplyDiplodocusMutationException("The task named " + getOriginTaskName() + " does not exist in the current model.");
        }
        if (_destinationTask==null){
            throw new ApplyDiplodocusMutationException("The task named " + getDestinationTaskName() + " does not exist in the current model.");
        }
        request.addOriginTask(_originTask);
        request.setDestinationTask(_destinationTask);

        return request;
    }

    @Override
    public void apply(TMLModeling<?> _tmlModel) throws ApplyDiplodocusMutationException {
        TMLRequest request = createElement(_tmlModel);
        if (parameters != null) {
            for (String parameter : parameters) {
                int type = 4;
                if (parameter.toUpperCase().equals("INT")) {
                    type = TMLType.NATURAL;
                } else if (parameter.toUpperCase().equals("BOOL")) {
                    type = TMLType.BOOLEAN;
                }
                request.addParam(new TMLType(type));
            }
        }
        _tmlModel.addRequest(request);
    }

    public static AddRequestConnectionMutation createFromString (String toParse) throws ParseDiplodocusMutationException {
        String[] tokens = DiplodocusMutationParser.tokenise(toParse);

        int index = DiplodocusMutationParser.indexOf(tokens,"BETWEEN");
        if (tokens.length <= index + 3) {
            throw new ParseDiplodocusMutationException("Missing task name. Expected syntax is add request connection connectionName between " +
                    "originTaskName and destinationTaskName");
        }
        String _originTaskName = tokens[index+1];
        String _destinationTaskName = tokens[index+3];

        if (tokens[index-1].toUpperCase().equals("CONNECTION")){
            throw new ParseDiplodocusMutationException("Missing or invalid connection name. Expected syntax is add request connection " +
                    "connectionName between originTaskName and destinationTaskName with connectionName != 'connection'");
        }

        boolean hasParameters = false;
        String _connectionName;
        if (DiplodocusMutationParser.indexOf(tokens,"(") != -1){
            hasParameters = true;
        }
        if (hasParameters){
            _connectionName = tokens[DiplodocusMutationParser.indexOf(tokens,"(")-1];
        } else {
            _connectionName = tokens[index - 1];
        }

        AddRequestConnectionMutation mutation = new AddRequestConnectionMutation(_originTaskName, _destinationTaskName, _connectionName);
        if (hasParameters){
            mutation.parameters = parseParameters(toParse);
        }
        mutation.setMutationType("TMLmutation");

        return mutation;
    }

}