/**
 * <copyright>
 * 
 * Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * Thales Corporate Services S.A.S - initial API and implementation
 * 
 * </copyright>
 */

package org.eclipse.egf.pattern.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.egf.model.pattern.Pattern;
import org.eclipse.egf.model.pattern.PatternContext;
import org.eclipse.egf.model.pattern.PatternException;
import org.eclipse.egf.model.pattern.PatternFactory;
import org.eclipse.egf.model.pattern.PatternParameter;
import org.eclipse.egf.model.pattern.Substitution;
import org.eclipse.egf.model.pattern.TypePatternSubstitution;
import org.eclipse.egf.pattern.extension.ExtensionHelper;
import org.eclipse.egf.pattern.extension.ExtensionHelper.MissingExtensionException;
import org.eclipse.egf.pattern.extension.PatternExtension;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;

/**
 * @author Thomas Guiu
 * 
 */
public class SubstitutionHelper {

    /**
     * This method applies the given substitutions to the given list of
     * patterns. Substitution is performed only if one candidate for replacement
     * can be executed (i.e. the preCondition is true)
     */
    public static List<Pattern> apply(PatternContext context, List<Pattern> patterns1, List<Object> parameterValues) throws PatternException {
        TypePatternSubstitution substitutions = (TypePatternSubstitution) context.getValue(PatternContext.PATTERN_SUBSTITUTIONS);
        if (substitutions == null || substitutions.getSubstitutions().isEmpty() || patterns1.isEmpty())
            return patterns1;

        List<Pattern> patterns = new ArrayList<Pattern>(patterns1);
        for (Substitution substitution : substitutions.getSubstitutions()) {
            Pattern[] array = patterns.toArray(new Pattern[patterns.size()]);
            for (Pattern pattern : array) {
                Pattern target = substitution.getReplacedElement();
                if (target != null && pattern.getID().equals(target.getID())) {
                    // if (!checkCondition(context, target, parameterValues)) {
                    // // if the pattern won't be applied, no need to
                    // // substitute it.
                    // continue;
                    // }

                    int index = patterns.indexOf(pattern);
                    EList<Pattern> replacement = substitution.getReplacement();
                    if (replacement != null) {
                        if (replacement.isEmpty()) {
                            patterns.remove(index);
                        } else {

                            // substitute patterns if at least one pattern from
                            // replacement list can apply
                            List<Pattern> toAdd = new ArrayList<Pattern>(replacement.size());
                            for (Pattern replacementPattern : replacement) {
                                if (checkCondition(context, replacementPattern, parameterValues)) {
                                    toAdd.add(replacementPattern);
                                }
                            }
                            if (!toAdd.isEmpty()) {
                                patterns.remove(index);
                                patterns.addAll(index, replacement);
                            }
                        }
                    }
                    break;
                }
            }
        }

        return patterns;
    }

    private static boolean checkCondition(PatternContext context, Pattern replacementPattern, List<Object> parameterValues) throws PatternException {
        try {

            PatternExtension extension = ExtensionHelper.getExtension(replacementPattern.getNature());
            Map<PatternParameter, Object> parameters = new HashMap<PatternParameter, Object>();
            if (replacementPattern.getAllParameters().size() != parameterValues.size())
                return false;
            int nb = replacementPattern.getAllParameters().size();
            for (int i = 0; i < nb; i++) {
                parameters.put(replacementPattern.getAllParameters().get(i), parameterValues.get(i));
            }
            return extension.createEngine(replacementPattern).checkCondition(context, parameters);
        } catch (MissingExtensionException e) {
            throw new PatternException(e);
        }

    }

    public static void apply(List<Pattern> patterns, TypePatternSubstitution substitutions) {
        if (substitutions == null || substitutions.getSubstitutions().isEmpty() || patterns.isEmpty())
            return;

        for (Substitution substitution : substitutions.getSubstitutions()) {
            Pattern[] array = patterns.toArray(new Pattern[patterns.size()]);
            for (Pattern pattern : array) {
                Pattern target = substitution.getReplacedElement();
                if (target != null && pattern.getID().equals(target.getID())) {
                    int index = patterns.indexOf(pattern);
                    patterns.remove(index);
                    if (substitution.getReplacement() != null)
                        patterns.addAll(index, substitution.getReplacement());
                }
            }
        }

    }

    public static TypePatternSubstitution merge(TypePatternSubstitution inputA, TypePatternSubstitution inputB) {
        TypePatternSubstitution result = PatternFactory.eINSTANCE.createTypePatternSubstitution();
        copySubstitutions(inputA, result);
        copySubstitutions(inputB, result);
        return result;
    }

    @SuppressWarnings("cast")
    private static void copySubstitutions(TypePatternSubstitution input, TypePatternSubstitution result) {
        if (input == null) {
            return;
        }
        for (Substitution substitution : input.getSubstitutions()) {
            // Preserve cast for backward compatibility
            Substitution newSub = (Substitution) EcoreUtil.copy(substitution);
            result.getSubstitutions().add(newSub);
        }
    }

}
