/*******************************************************************************
 * Copyright (c) 2019 Christian W. Damus and others.
 *
 * All rights reserved. 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:
 * Christian W. Damus - initial API and implementation
 ******************************************************************************/
package org.eclipse.emfforms.swt.internal.reference.table;

import static java.util.Collections.singleton;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.common.spi.UniqueSetting;
import org.eclipse.emf.ecp.ui.view.swt.reference.SelectionCompositeStrategy;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VFeatureDomainModelReferenceSegment;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.model.VViewModelLoadingProperties;
import org.eclipse.emf.ecp.view.spi.model.VViewModelProperties;
import org.eclipse.emf.ecp.view.spi.provider.ViewProviderHelper;
import org.eclipse.emf.ecp.view.spi.table.model.VTableControl;
import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
import org.eclipse.emfforms.bazaar.Bid;
import org.eclipse.emfforms.bazaar.Create;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
import org.eclipse.emfforms.view.spi.multisegment.model.MultiSegmentUtil;
import org.eclipse.emfforms.view.spi.multisegment.model.VMultiDomainModelReferenceSegment;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * Provider of a selection composite strategy that builds a selection table viewer
 * from a {@linkplain VTableControl table control model}.
 * 
 * @since 1.22
 */
@Component(name = "selectionTableCompositeStrategyProvider")
public class SelectionTableCompositeStrategyProvider implements SelectionCompositeStrategy.Provider {

	/**
	 * Filter key for view registration to apply the view to the context of the selection
	 * table composite specifically in the case that some other view is also available
	 * that is intended for the editor. The value of the filter is the name of the reference
	 * feature for which objects are to be selected.
	 */
	public static final String VIEW_FILTER_KEY = "selectionTableComposite"; //$NON-NLS-1$

	private static final Double BID = 1.0;

	private final Map<UniqueSetting, VTableControl> recentlyQueriedTables = new HashMap<>();

	private EMFFormsDatabindingEMF databinding;

	/**
	 * Initializes me.
	 */
	public SelectionTableCompositeStrategyProvider() {
		super();
	}

	/**
	 * Queries my bid on a selection table composite strategy for selection of objects to add
	 * to the given {@code reference} of an {@code owner} object.
	 *
	 * @param owner the owner of the reference to be edited
	 * @param reference the reference to which to add objects
	 *
	 * @return my bid, or {@code null} if I have nothing to offer
	 */
	@Bid
	public Double provides(EObject owner, EReference reference) {
		final UniqueSetting key = UniqueSetting.createSetting(owner, reference);
		final VTableControl table = getTableControl(key);
		if (table != null) {
			recentlyQueriedTables.put(key, table);
		}
		return table != null ? BID : null;
	}

	private VTableControl getTableControl(UniqueSetting key) {
		VTableControl result = recentlyQueriedTables.get(key);
		if (result == null) {
			result = getTableControl(key.getEObject(), key.getEStructuralFeature());
		}
		return result;
	}

	/**
	 * Obtain the view model for selecting objects to add the the {@code reference}
	 * of an {@code owner}.
	 *
	 * @param owner the owner of the {@code reference} being edited
	 * @param feature the reference feature being edited
	 * @return the view model, or {@code null} if there is none
	 */
	protected VTableControl getTableControl(EObject owner, EStructuralFeature feature) {
		VTableControl result = null;

		final VViewModelProperties loadingProperties = getLoadingProperties(owner, feature);

		// Require our filter property to be sure only to get views that are specifically
		// designed for usage in the selection composite
		final VView view = ViewProviderHelper.getView(owner, loadingProperties, singleton(VIEW_FILTER_KEY));

		if (view != null) {
			// It must have a table for our reference
			result = findTableControl(view, owner, feature);
		}

		return result;
	}

	/**
	 * Obtain the view model loading properties for filtering the applicable view models.
	 *
	 * @param owner the owner of the {@code reference} being edited
	 * @param feature the reference feature being edited
	 * @return the view model filter properties
	 */
	protected VViewModelProperties getLoadingProperties(EObject owner, EStructuralFeature feature) {
		final VViewModelLoadingProperties result = VViewFactory.eINSTANCE.createViewModelLoadingProperties();
		result.addNonInheritableProperty(VIEW_FILTER_KEY, feature.getName());
		return result;
	}

	/**
	 * Create my selection table composite strategy for selection of objects to add
	 * to the given {@code reference} of an {@code owner} object.
	 *
	 * @param owner the owner of the reference to be edited
	 * @param reference the reference to which to add objects
	 *
	 * @return my bid, or {@code null} if I have nothing to offer
	 */
	@Create
	public SelectionCompositeStrategy create(EObject owner, EReference reference) {
		SelectionCompositeStrategy result = null;
		final UniqueSetting key = UniqueSetting.createSetting(owner, reference);
		final VTableControl table = getTableControl(key);

		if (table != null) {
			// Don't keep the cache in case the next query would have a different result
			recentlyQueriedTables.remove(key);
			result = strategy(table);
		}

		return result;
	}

	private SelectionCompositeStrategy strategy(VTableControl table) {
		return (owner, reference, extent) -> new TableSelectionCompositeImpl(
			extent, table, owner, reference);
	}

	/**
	 * Search for a table control in the given {@code view} that edits a {@code feature}.
	 *
	 * @param view a view to search
	 * @param owner the owner of the {@code feature} being edited
	 * @param feature the feature to be edited
	 *
	 * @return a table editing the {@code feature}, or {@code null} if none
	 */
	private VTableControl findTableControl(VView view, EObject owner, EStructuralFeature feature) {
		VTableControl result = null;

		for (final Iterator<EObject> iter = view.eAllContents(); result == null && iter.hasNext();) {
			final EObject next = iter.next();
			if (next instanceof VTableControl) {
				final VTableControl table = (VTableControl) next;
				final VDomainModelReference dmr = table.getDomainModelReference();
				if (dmr == null) {
					continue;
				}

				if (dmr.getSegments().isEmpty() && dmr instanceof VTableDomainModelReference) {
					// The TableDMRConverter ignores single-valued references, but we
					// have to let them be specified anyways because it's the only
					// thing that can provide the column DMRs
					final VTableDomainModelReference tdmr = (VTableDomainModelReference) dmr;
					if (tdmr.getDomainModelEFeature() == feature
						|| resolvesTo(tdmr.getDomainModelReference(), owner, feature)) {

						// That's the one
						result = table;
					}
				} else if (!dmr.getSegments().isEmpty() && MultiSegmentUtil.getMultiSegment(dmr).isPresent()) {
					// The MultiSegmentConverter does not handle single-value reference, but we have to let them be
					// specified anyways because it's the only thing that can provide the column DMRs.
					// Copy the dmr and replace the multi segment with a feature segment in the copied version. See if
					// this can be resolved to our target feature.
					final VDomainModelReference copiedDmr = EcoreUtil.copy(dmr);
					final VMultiDomainModelReferenceSegment multiSegment = MultiSegmentUtil.getMultiSegment(copiedDmr)
						.get();
					copiedDmr.getSegments().remove(multiSegment);
					final VFeatureDomainModelReferenceSegment segment = VViewFactory.eINSTANCE
						.createFeatureDomainModelReferenceSegment();
					segment.setDomainModelFeature(multiSegment.getDomainModelFeature());
					copiedDmr.getSegments().add(segment);
					if (resolvesTo(copiedDmr, owner, feature)) {
						result = table;
					}
				} else if (resolvesTo(dmr, owner, feature)) {
					// That's the one
					result = table;
				}
			}
		}

		return result;
	}

	private boolean resolvesTo(VDomainModelReference dmr, EObject owner, EStructuralFeature feature) {
		boolean result = false;

		EStructuralFeature.Setting setting;
		try {
			setting = databinding.getSetting(dmr, owner);
			result = setting != null && setting.getEStructuralFeature() == feature;
		} catch (final DatabindingFailedException e) {
			// This table is of no use to us
		}

		return result;
	}

	//
	// Component lifecycle and dependencies
	//

	/**
	 * Inject my data binding service dependency.
	 *
	 * @param databinding the data binding service to set
	 */
	@Reference(unbind = "-")
	void setDatabinding(EMFFormsDatabindingEMF databinding) {
		this.databinding = databinding;
	}

}
