/*******************************************************************************
 * Copyright (c) 2012, 2020 Original authors and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Original authors and others - initial API and implementation
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.group.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;

/**
 * A thread-safe implementation of {@link IRowGroupModel} which is optimised for
 * larger data-sets (it should cope with at least 10k rows spread across 2-300
 * groups).
 *
 * @author Stefan Bolton
 *
 * @param <T>
 */
public class RowGroupModel<T> implements IRowGroupModel<T> {

    // A map of top-level group names-to-RowGroups.
    private final Map<String, IRowGroup<T>> namesToGroups;

    // A performance cache of rows-to-row group nodes. Kept directly in sync
    // with the model.
    private final Map<T, IRowGroup<T>> rowToGroups;

    // Row group change listeners.
    private final Set<IRowGroupModelListener> listeners;

    // A convenience cache of row indexes to/from row objects. Items are added
    // on demand
    // from the layers as-and-when they are needed.
    private final RowCache<T> rowCache;

    // For big model changes it can be easier to suppress model change
    // notifications and fire a single one.
    private boolean suppressNoficiations;

    public RowGroupModel() {
        this.rowToGroups = new ConcurrentHashMap<T, IRowGroup<T>>();
        this.namesToGroups = new ConcurrentHashMap<String, IRowGroup<T>>();
        this.rowCache = new RowCache<T>();
        this.listeners = new HashSet<IRowGroupModelListener>();
        this.suppressNoficiations = false;
    }

    @Override
    public T getRowFromIndexCache(final int rowIndex) {
        return this.rowCache.getRowFromIndexCache(rowIndex);
    }

    @Override
    public int getIndexFromRowCache(final T row) {
        return this.rowCache.getIndexFromRowCache(row);
    };

    @Override
    public void invalidateIndexCache() {
        this.rowCache.invalidateIndexCache();
    }

    @Override
    public void setDataProvider(IRowDataProvider<T> dataProvider) {
        this.rowCache.setDataProvider(dataProvider);
    }

    @Override
    public IRowDataProvider<T> getDataProvider() {
        return this.rowCache.getDataProvider();
    }

    /**
     * <p>
     * Notify any {@link IRowGroupModelListener}s that something in the model
     * has changed.
     * </p>
     */
    @Override
    public void notifyListeners() {
        invalidateIndexCache();

        if (!this.suppressNoficiations) {
            for (IRowGroupModelListener listener : this.listeners) {
                listener.rowGroupModelChanged();
            }
        }
    }

    /**
     * Set to true to stop model change notifications.
     *
     * @param suppressNoficiations
     */
    public void setSuppressNoficiations(boolean suppressNoficiations) {
        this.suppressNoficiations = suppressNoficiations;
    }

    public boolean isSuppressNoficiations() {
        return this.suppressNoficiations;
    }

    void addMemberRow(final T row, final RowGroup<T> rowGroup) {
        this.rowToGroups.put(row, rowGroup);
    }

    void removeMemberRow(final T row) {
        this.rowToGroups.remove(row);
    }

    @Override
    public void addRowGroups(final List<IRowGroup<T>> rowGroups) {

        // Add the group into the model now.
        for (IRowGroup<T> rowGroup : rowGroups) {
            this.namesToGroups.put(rowGroup.getGroupName(), rowGroup);
        }

        notifyListeners();
    }

    @Override
    public boolean addRowGroup(final IRowGroup<T> rowGroup) {

        // Only allow unique names.
        if (this.namesToGroups.containsKey(rowGroup.getGroupName())) {
            return false;
        }

        // Add the group into the model now.
        this.namesToGroups.put(rowGroup.getGroupName(), rowGroup);

        notifyListeners();
        return true;
    }

    @Override
    public boolean removeRowGroup(final IRowGroup<T> rowGroup) {

        boolean removed = this.namesToGroups.containsKey(rowGroup.getGroupName());

        if (removed) {
            // Remove the group itself now.
            this.namesToGroups.remove(rowGroup.getGroupName());
            notifyListeners();
        }

        return removed;
    }

    @Override
    public List<IRowGroup<T>> getRowGroups() {
        return Collections.unmodifiableList(new ArrayList<IRowGroup<T>>(
                this.namesToGroups.values()));
    }

    @Override
    public IRowGroup<T> getRowGroupForName(final String groupName) {
        return this.namesToGroups.get(groupName);
    }

    @Override
    public IRowGroup<T> getRowGroupForRow(T row) {

        if (this.rowToGroups.containsKey(row)) {
            return getUltimateParent(this.rowToGroups.get(row));
        }

        return null;
    }

    private IRowGroup<T> getUltimateParent(IRowGroup<T> group) {
        return (group.getParentGroup() == null ? group
                : getUltimateParent(group.getParentGroup()));
    }

    @Override
    public boolean isEmpty() {
        return this.namesToGroups.isEmpty();
    }

    @Override
    public void clear() {
        this.namesToGroups.clear();
        this.rowToGroups.clear();
        this.rowCache.invalidateIndexCache();
        notifyListeners();
    }

    @Override
    public void registerRowGroupModelListener(
            final IRowGroupModelListener listener) {
        this.listeners.add(listener);
    }

    @Override
    public void unregisterRowGroupModelListener(
            final IRowGroupModelListener listener) {
        this.listeners.remove(listener);
    }

    @Override
    public void saveState(String prefix, Properties properties) {
    }

    @Override
    public void loadState(String prefix, Properties properties) {
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(" ===== Row Group Model ==== \n"); //$NON-NLS-1$

        synchronized (this.namesToGroups) {
            for (IRowGroup<T> rowGroup : this.namesToGroups.values()) {
                sb.append(((RowGroup<T>) rowGroup).toString());
            }
        }

        return sb.toString();
    }

    private class RowCache<E> {

        private IRowDataProvider<E> dataProvider;

        private final Map<Integer, E> indexesToRows;
        private final Map<E, Integer> rowsToIndexes;

        public RowCache() {
            this.indexesToRows = new LinkedHashMap<Integer, E>();
            this.rowsToIndexes = new LinkedHashMap<E, Integer>();
        }

        public IRowDataProvider<E> getDataProvider() {
            return this.dataProvider;
        }

        public void setDataProvider(IRowDataProvider<E> dataProvider) {
            this.dataProvider = dataProvider;
        }

        public E getRowFromIndexCache(final int rowIndex) {
            if (this.indexesToRows.containsKey(rowIndex)) {
                return this.indexesToRows.get(rowIndex);
            }

            final E row = this.dataProvider.getRowObject(rowIndex);

            // If the row we want to use is already in use, then clear the
            // cache.
            if (this.rowsToIndexes.containsKey(row)) {
                invalidateIndexCache();
            }

            this.rowsToIndexes.put(row, rowIndex);
            this.indexesToRows.put(rowIndex, row);
            return row;
        }

        public int getIndexFromRowCache(final E row) {
            if (this.rowsToIndexes.containsKey(row)) {
                return this.rowsToIndexes.get(row);
            }

            final int rowIndex = this.dataProvider.indexOfRowObject(row);

            // If the index we want to use is already in use, then clear the
            // cache.
            if (this.indexesToRows.containsKey(rowIndex)) {
                invalidateIndexCache();
            }

            this.indexesToRows.put(rowIndex, row);
            this.rowsToIndexes.put(row, rowIndex);
            return rowIndex;
        }

        public void invalidateIndexCache() {
            this.indexesToRows.clear();
            this.rowsToIndexes.clear();
        }
    }
}
