/*******************************************************************************
 * Copyright (c) 2011 Obeo.
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.synchronizer;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

/**
 * A refresh plan holds the list of operation : creation, refreshment or
 * removing needed to update the output model.
 * 
 * @author Cedric Brun <cedric.brun@obeo.fr>
 * 
 */
public class RefreshPlan {

    private SignatureProvider signatureProvider;

    private Map<Signature, OutputDescriptor> outputToCreate;

    private Map<Signature, CreatedOutput> outputToRefresh;

    private Map<Signature, CreatedOutput> outputToUpdateMapping;

    private Multimap<Signature, CreatedOutput> outputToRemove;

    /**
     * Creates a new RefreshPlan.
     * 
     * @param signProvider
     *            the {@link SignatureProvider} to use
     */
    public RefreshPlan(SignatureProvider signProvider) {
        outputToCreate = new LinkedHashMap<>();
        outputToRefresh = new LinkedHashMap<>();
        outputToRemove = HashMultimap.create();
        outputToUpdateMapping = new HashMap<>();
        this.signatureProvider = signProvider;

    }

    public Collection<CreatedOutput> getDescriptorToUpdateMapping() {
        return outputToUpdateMapping.values();
    }

    /**
     * Adds a PreRefreshStatus to the RefreshPlan.
     * 
     * @param pre
     *            the PreRefreshStatus to add to the refresh plan
     */
    public void addPreviousStatus(Iterable<? extends CreatedOutput> pre) {
        for (CreatedOutput desc : pre) {
            shouldBeRemoved(desc);
        }
    }

    private void shouldBeRemoved(CreatedOutput desc) {
        outputToRemove.put(signatureProvider.getSignature(desc.getDescriptor()), desc);
    }

    public void appendOutputDescritorsKeepingTheMostSpecific(Collection<? extends OutputDescriptor> computeDescriptors) {

        for (OutputDescriptor newDescriptor : computeDescriptors) {
            Option<CreatedOutput> wasHere = getDescriptorAlreadyHereWeWantToKeep(newDescriptor);
            if (wasHere.some()) {
                if (wasHere.get().getDescriptor().getIndex() != newDescriptor.getIndex()) {
                    shouldBeReordered(wasHere.get(), newDescriptor.getIndex());
                }
                if (wasHere.get().getDescriptor().getMapping() != newDescriptor.getMapping()) {
                    shouldUpdateTheMapping(wasHere.get(), newDescriptor.getMapping());
                }
                shouldBeRefreshed(wasHere.get());
            } else {
                shouldBeCreated(newDescriptor);
            }
        }
    }

    private void shouldUpdateTheMapping(CreatedOutput createdOutput, Mapping mapping) {
        createdOutput.setNewMapping(mapping);
        Signature signature = signatureProvider.getSignature(createdOutput.getDescriptor());
        // CreatedOutput previousVersionOutput =
        // outputToRemove.remove(signature);
        // previousVersionOutput.setNewMapping(mapping);
        outputToUpdateMapping.put(signature, createdOutput);

    }

    private void shouldBeCreated(OutputDescriptor newDescriptor) {
        /*
         * First let's check if an equivalent descriptor is already registered
         * to be created.
         */
        Signature signature = signatureProvider.getSignature(newDescriptor);
        if (!outputToCreate.containsKey(signature) && !outputToRefresh.containsKey(signature)) {
            outputToCreate.put(signature, newDescriptor);
        }
    }

    private void shouldBeRefreshed(CreatedOutput outputDescriptor) {
        Signature signature = signatureProvider.getSignature(outputDescriptor.getDescriptor());
        Option<CreatedOutput> element = getDescriptorAlreadyHereWeWantToKeep(outputDescriptor.getDescriptor());
        if (element.some()) {
            outputToRemove.remove(signature, element.get());
            if (!outputToRefresh.containsKey(signature)) {
                outputToRefresh.put(signature, element.get());
            }
        }
    }

    private void shouldBeReordered(CreatedOutput newDescriptor, int nextIndex) {
        newDescriptor.setNewIndex(nextIndex);
    }

    private Option<CreatedOutput> getDescriptorAlreadyHereWeWantToKeep(OutputDescriptor newDescriptor) {
        Collection<CreatedOutput> toRemove = outputToRemove.get(signatureProvider.getSignature(newDescriptor));
        if (toRemove.size() > 0) {
            return Options.newSome(toRemove.iterator().next());
        }
        return Options.newNone();
    }

    public Collection<CreatedOutput> getDescriptorsToDelete() {
        return outputToRemove.values();
    }

    public Collection<OutputDescriptor> getDescriptorsToCreate() {
        return outputToCreate.values();
    }

    public Collection<CreatedOutput> getDescriptorsToRefresh() {
        return outputToRefresh.values();
    }

}
