/*******************************************************************************
 * 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
 *     Uwe Peuker <dev@upeuker.net> - Bug 500788
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.export;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.nebula.widgets.nattable.Messages;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.formula.command.DisableFormulaEvaluationCommand;
import org.eclipse.nebula.widgets.nattable.formula.command.EnableFormulaEvaluationCommand;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.print.command.PrintEntireGridCommand;
import org.eclipse.nebula.widgets.nattable.print.command.TurnViewportOffCommand;
import org.eclipse.nebula.widgets.nattable.print.command.TurnViewportOnCommand;
import org.eclipse.nebula.widgets.nattable.resize.AutoResizeHelper;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.summaryrow.command.CalculateSummaryRowValuesCommand;
import org.eclipse.nebula.widgets.nattable.ui.ExceptionDialog;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;

/**
 * This class is used to perform exports of a NatTable or {@link ILayer} in a
 * NatTable composition. The exporter to use can be configured via
 * {@link IConfigRegistry} or directly given as method parameter.
 *
 * @see ExportConfigAttributes#EXPORTER
 * @see ExportConfigAttributes#TABLE_EXPORTER
 */
public class NatExporter {

    private static final Log LOG = LogFactory.getLog(NatExporter.class);

    /**
     * The {@link Shell} that should be used to open sub-dialogs and perform
     * export operations in a background thread.
     *
     * @since 1.5
     */
    protected final Shell shell;
    /**
     * Flag that indicates if the created export result should be opened after
     * the export is finished.
     *
     * @since 1.5
     */
    protected boolean openResult = true;
    /**
     * Flag that indicates that the export succeeded. Used to determine whether
     * the export result can be opened or not.
     *
     * @since 1.5
     */
    protected boolean exportSucceeded = true;
    /**
     * Flag to configure whether in-memory pre-rendering is enabled or not. This
     * is necessary in case content painters are used that are configured for
     * content based auto-resizing.
     *
     * @since 1.5
     */
    protected boolean preRender = true;
    /**
     * Flag to configure whether the export should be performed asynchronously
     * or synchronously. By default this flag is set to <code>true</code> and
     * the decision whether the execution should be performed synchronously or
     * not is made based on whether a {@link Shell} is set or not. If a
     * {@link Shell} is set and this flag is set to <code>false</code> the
     * execution is performed synchronously.
     *
     * @since 1.6
     */
    private boolean runAsynchronously = true;

    /**
     * Create a new {@link NatExporter}.
     *
     * @param shell
     *            The {@link Shell} that should be used to open sub-dialogs and
     *            perform export operations in a background thread. Can be
     *            <code>null</code> but could lead to
     *            {@link NullPointerException}s if {@link IExporter} are
     *            configured, that use a {@link FileOutputStreamProvider}.
     */
    public NatExporter(Shell shell) {
        this(shell, false);
    }

    /**
     * Create a new {@link NatExporter}.
     *
     * @param shell
     *            The {@link Shell} that should be used to open sub-dialogs and
     *            perform export operations in a background thread. Can be
     *            <code>null</code> but could lead to
     *            {@link NullPointerException}s if {@link IExporter} are
     *            configured, that use a {@link FileOutputStreamProvider}.
     * @param executeSynchronously
     *            Configure whether the export should be performed
     *            asynchronously or synchronously. By default the decision
     *            whether the execution should be performed synchronously or not
     *            is made based on whether a {@link Shell} is set or not. If a
     *            {@link Shell} is set and this flag is set to <code>true</code>
     *            the execution is performed synchronously.
     *
     * @since 1.6
     */
    public NatExporter(Shell shell, boolean executeSynchronously) {
        this.shell = shell;
        this.runAsynchronously = !executeSynchronously;
    }

    /**
     * Exports a single {@link ILayer} using the {@link ILayerExporter}
     * registered in the {@link IConfigRegistry} for the key
     * {@link ExportConfigAttributes#EXPORTER}.
     *
     * @param layer
     *            The {@link ILayer} to export, usually a NatTable instance.
     * @param configRegistry
     *            The {@link IConfigRegistry} of the NatTable instance to
     *            export, that contains the necessary export configurations.
     */
    public void exportSingleLayer(
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        ILayerExporter exporter = configRegistry.getConfigAttribute(
                ExportConfigAttributes.EXPORTER,
                DisplayMode.NORMAL);

        exportSingleLayer(exporter, layer, configRegistry);
    }

    /**
     * Exports a single {@link ILayer} using the given {@link ILayerExporter}.
     *
     * @param exporter
     *            The {@link ILayerExporter} to use for exporting.
     * @param layer
     *            The {@link ILayer} to export, usually a NatTable instance.
     * @param configRegistry
     *            The {@link IConfigRegistry} of the NatTable instance to
     *            export, that contains the necessary export configurations.
     *
     * @since 1.5
     */
    public void exportSingleLayer(
            final ILayerExporter exporter,
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        exportSingle(exporter, (exp, outputStream) -> {
            try {
                exp.exportBegin(outputStream);

                exportLayer(exp, outputStream, "", layer, configRegistry); //$NON-NLS-1$

                exp.exportEnd(outputStream);
            } catch (IOException e) {
                // exception is handled in the caller
                throw new RuntimeException(e);
            }
        });
    }

    /**
     * Exports a single {@link ILayer} using the {@link ILayerExporter}
     * registered in the {@link IConfigRegistry} for the key
     * {@link ExportConfigAttributes#EXPORTER}.
     *
     * @param layer
     *            The {@link ILayer} to export, usually a NatTable instance.
     * @param configRegistry
     *            The {@link IConfigRegistry} of the NatTable instance to
     *            export, that contains the necessary export configurations.
     *
     * @since 1.5
     */
    public void exportSingleTable(
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        final ITableExporter exporter = configRegistry.getConfigAttribute(
                ExportConfigAttributes.TABLE_EXPORTER,
                DisplayMode.NORMAL);

        exportSingleTable(exporter, layer, configRegistry);
    }

    /**
     * Exports a single {@link ILayer} using the given {@link ITableExporter}.
     *
     * @param exporter
     *            The {@link ITableExporter} to use for exporting.
     * @param layer
     *            The {@link ILayer} to export, usually a NatTable instance.
     * @param configRegistry
     *            The {@link IConfigRegistry} of the NatTable instance to
     *            export, that contains the necessary export configurations.
     *
     * @since 1.5
     */
    public void exportSingleTable(
            final ITableExporter exporter,
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        exportSingle(exporter, (exp, outputStream) -> exportLayer(exp, outputStream, layer, configRegistry));
    }

    /**
     * Functional interface used to specify how the export should be performed
     * for different exporter interface implementations. Can be removed once the
     * source API level is updated to Java 1.8
     *
     * @param <T>
     * @param <U>
     */
    private interface BiConsumer<T, U> {
        void apply(T t, U u);
    }

    /**
     *
     * @param exporter
     *            The {@link IExporter} to use for exporting.
     * @param executable
     *            The consumer implementation that is used to execute the export
     *            and produce the output to an {@link OutputStream}
     */
    private <T extends IExporter> void exportSingle(final T exporter, final BiConsumer<T, OutputStream> executable) {

        Runnable exportRunnable = () -> {
            final OutputStream outputStream = getOutputStream(exporter);
            if (outputStream != null) {
                try {
                    executable.apply(exporter, outputStream);

                    NatExporter.this.exportSucceeded = true;
                } catch (Exception e1) {
                    NatExporter.this.exportSucceeded = false;
                    handleExportException(e1);
                } finally {
                    try {
                        outputStream.close();
                    } catch (IOException e2) {
                        LOG.error("Failed to close the output stream", e2); //$NON-NLS-1$
                    }
                }

                openExport(exporter);
            }
        };

        if (this.shell != null) {
            // Run with the SWT display so that the progress bar can paint
            if (this.runAsynchronously) {
                this.shell.getDisplay().asyncExec(exportRunnable);
            } else {
                this.shell.getDisplay().syncExec(exportRunnable);
            }
        } else {
            // execute in the current thread
            exportRunnable.run();
        }
    }

    /**
     * Export multiple NatTable instances to one file by using the given
     * ILayerExporter.
     *
     * @param exporter
     *            The ILayerExporter to use for exporting.
     * @param natTablesMap
     *            The NatTable instances to export. They keys in the map will be
     *            used as sheet titles while the values are the instances to
     *            export.
     */
    public void exportMultipleNatTables(
            final ILayerExporter exporter,
            final Map<String, NatTable> natTablesMap) {
        exportMultipleNatTables(exporter, natTablesMap, false, null);
    }

    /**
     * Export multiple NatTable instances to one file by using the given
     * ILayerExporter.
     *
     * @param exporter
     *            The ILayerExporter to use for exporting.
     * @param natTablesMap
     *            The NatTable instances to export. They keys in the map will be
     *            used as sheet titles while the values are the instances to
     *            export.
     * @param exportOnSameSheet
     *            Flag to configure whether multiple NatTable instances should
     *            be exported on the same sheet or not.
     * @param sheetName
     *            The sheet name that should be used in case of exporting
     *            multiple NatTables on a single sheet.
     * @since 1.5
     */
    public void exportMultipleNatTables(
            final ILayerExporter exporter,
            final Map<String, NatTable> natTablesMap,
            final boolean exportOnSameSheet,
            final String sheetName) {

        Runnable exportRunnable = () -> {
            final OutputStream outputStream = getOutputStream(exporter);
            if (outputStream != null) {
                try {
                    exporter.exportBegin(outputStream);

                    if (exportOnSameSheet) {
                        exporter.exportLayerBegin(outputStream, sheetName);
                    }

                    for (String name : natTablesMap.keySet()) {
                        NatTable natTable = natTablesMap.get(name);
                        exportLayer(exporter, outputStream, name, natTable, natTable.getConfigRegistry(), !exportOnSameSheet);
                    }

                    if (exportOnSameSheet) {
                        exporter.exportLayerEnd(outputStream, sheetName);
                    }

                    exporter.exportEnd(outputStream);

                    NatExporter.this.exportSucceeded = true;
                } catch (Exception e1) {
                    NatExporter.this.exportSucceeded = false;
                    handleExportException(e1);
                } finally {
                    try {
                        outputStream.close();
                    } catch (IOException e2) {
                        LOG.error("Failed to close the output stream", e2); //$NON-NLS-1$
                    }
                }
            }

            openExport(exporter);
        };

        if (this.shell != null) {
            // Run with the SWT display so that the progress bar can paint
            if (this.runAsynchronously) {
                this.shell.getDisplay().asyncExec(exportRunnable);
            } else {
                this.shell.getDisplay().syncExec(exportRunnable);
            }
        } else {
            exportRunnable.run();
        }
    }

    /**
     * Exports the given layer to the outputStream using the provided exporter.
     * The {@link ILayerExporter#exportBegin(OutputStream)} method should be
     * called before this method is invoked, and
     * {@link ILayerExporter#exportEnd(OutputStream)} should be called after
     * this method returns. If multiple layers are being exported as part of a
     * single logical export operation, then
     * {@link ILayerExporter#exportBegin(OutputStream)} will be called once at
     * the very beginning, followed by n calls to this method, and finally
     * followed by {@link ILayerExporter#exportEnd(OutputStream)}.
     *
     * <p>
     * <b>Note:</b> This method calls
     * {@link #exportLayer(ILayerExporter, OutputStream, String, ILayer, IConfigRegistry, boolean)}
     * with the parameter <i>initExportLayer</i> set to <code>true</code>.
     * </p>
     *
     * @param exporter
     *            The {@link ILayerExporter} that should be used for exporting.
     * @param outputStream
     *            The {@link OutputStream} that should be used to write the
     *            export to.
     * @param layerName
     *            The name that should be set as sheet name of the export.
     * @param layer
     *            The {@link ILayer} that should be exported.
     * @param configRegistry
     *            The {@link IConfigRegistry} needed to retrieve the export
     *            configurations.
     */
    protected void exportLayer(
            final ILayerExporter exporter,
            final OutputStream outputStream,
            final String layerName,
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        exportLayer(exporter, outputStream, layerName, layer, configRegistry, true);
    }

    /**
     * Exports the given layer to the outputStream using the provided exporter.
     * The {@link ILayerExporter#exportBegin(OutputStream)} method should be
     * called before this method is invoked, and
     * {@link ILayerExporter#exportEnd(OutputStream)} should be called after
     * this method returns. If multiple layers are being exported as part of a
     * single logical export operation, then
     * {@link ILayerExporter#exportBegin(OutputStream)} will be called once at
     * the very beginning, followed by n calls to this method, and finally
     * followed by {@link ILayerExporter#exportEnd(OutputStream)}.
     *
     * @param exporter
     *            The {@link ILayerExporter} that should be used for exporting.
     * @param outputStream
     *            The {@link OutputStream} that should be used to write the
     *            export to.
     * @param layerName
     *            The name that should be set as sheet name of the export.
     * @param layer
     *            The {@link ILayer} that should be exported.
     * @param configRegistry
     *            The {@link IConfigRegistry} needed to retrieve the export
     *            configurations.
     * @param initExportLayer
     *            flag to configure whether
     *            {@link ILayerExporter#exportLayerBegin(OutputStream, String)}
     *            and
     *            {@link ILayerExporter#exportLayerEnd(OutputStream, String)}
     *            should be called or not. Should be set to <code>true</code> if
     *            multiple NatTable instances should be exported on the same
     *            sheet.
     * @since 1.5
     */
    protected void exportLayer(
            final ILayerExporter exporter,
            final OutputStream outputStream,
            final String layerName,
            final ILayer layer,
            final IConfigRegistry configRegistry,
            final boolean initExportLayer) {

        exportLayer(new ITableExporter() {

            @Override
            public void exportTable(Shell shell, ProgressBar progressBar, OutputStream outputStream,
                    ILayer layer, IConfigRegistry configRegistry) throws IOException {

                if (initExportLayer) {
                    exporter.exportLayerBegin(outputStream, layerName);
                }

                int layerHeight = layer.getHeight();

                for (int rowPosition = 0; rowPosition < layer.getRowCount(); rowPosition++) {
                    if (layer.getRowHeightByPosition(rowPosition) > 0
                            && layer.getStartYOfRowPosition(rowPosition) < layerHeight) {
                        exporter.exportRowBegin(outputStream, rowPosition);
                        if (progressBar != null) {
                            progressBar.setSelection(rowPosition);
                        }

                        for (int columnPosition = 0; columnPosition < layer.getColumnCount(); columnPosition++) {
                            ILayerCell cell = layer.getCellByPosition(columnPosition, rowPosition);
                            if (cell != null) {
                                IExportFormatter exportFormatter = configRegistry.getConfigAttribute(
                                        ExportConfigAttributes.EXPORT_FORMATTER,
                                        cell.getDisplayMode(),
                                        cell.getConfigLabels());
                                Object exportDisplayValue = exportFormatter.formatForExport(cell, configRegistry);

                                exporter.exportCell(outputStream, exportDisplayValue, cell, configRegistry);
                            }
                        }

                        exporter.exportRowEnd(outputStream, rowPosition);
                    }
                }

                if (initExportLayer) {
                    exporter.exportLayerEnd(outputStream, layerName);
                }
            }

            @Override
            public OutputStream getOutputStream(Shell shell) {
                return exporter.getOutputStream(shell);
            }

            @Override
            public Object getResult() {
                return exporter.getResult();
            }
        }, outputStream, layer, configRegistry);
    }

    /**
     * Exports the given {@link ILayer} to the given {@link OutputStream} using
     * the provided {@link ITableExporter}.
     *
     * @param exporter
     *            The {@link ITableExporter} that should be used for exporting.
     * @param outputStream
     *            The {@link OutputStream} that should be used to write the
     *            export to.
     * @param layer
     *            The {@link ILayer} that should be exported.
     * @param configRegistry
     *            The {@link IConfigRegistry} needed to retrieve the export
     *            configurations.
     *
     * @since 1.5
     */
    protected void exportLayer(
            final ITableExporter exporter,
            final OutputStream outputStream,
            final ILayer layer,
            final IConfigRegistry configRegistry) {

        if (this.preRender) {
            AutoResizeHelper.autoResize(layer, configRegistry);
        }

        IClientAreaProvider originalClientAreaProvider = layer.getClientAreaProvider();

        // This needs to be done so that the layer can return all the cells
        // not just the ones visible in the viewport
        layer.doCommand(new TurnViewportOffCommand());
        setClientAreaToMaximum(layer);

        // if a SummaryRowLayer is in the layer stack, we need to ensure that
        // the values are calculated
        layer.doCommand(new CalculateSummaryRowValuesCommand());

        // if a FormulaDataProvider is involved, we need to ensure that the
        // formula evaluation is disabled so the formula itself is exported
        // instead of the calculated value
        layer.doCommand(new DisableFormulaEvaluationCommand());

        ProgressBar progressBar = null;

        if (this.shell != null) {
            Shell childShell = new Shell(this.shell.getDisplay(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
            childShell.setText(Messages.getString("NatExporter.exporting")); //$NON-NLS-1$

            int endRow = layer.getRowCount() - 1;

            progressBar = new ProgressBar(childShell, SWT.SMOOTH);
            progressBar.setMinimum(0);
            progressBar.setMaximum(endRow);
            progressBar.setBounds(0, 0, 400, 25);
            progressBar.setFocus();

            childShell.pack();
            childShell.open();
        }

        try {
            exporter.exportTable(this.shell, progressBar, outputStream, layer, configRegistry);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // These must be fired at the end of the thread execution
            layer.setClientAreaProvider(originalClientAreaProvider);
            layer.doCommand(new TurnViewportOnCommand());

            layer.doCommand(new EnableFormulaEvaluationCommand());

            if (progressBar != null) {
                Shell childShell = progressBar.getShell();
                progressBar.dispose();
                childShell.dispose();
            }
        }
    }

    /**
     * Increase the client area so it can include the whole {@link ILayer}.
     *
     * @param layer
     *            The {@link ILayer} for which the client area should be
     *            maximized.
     *
     * @since 1.5
     */
    protected void setClientAreaToMaximum(ILayer layer) {
        final Rectangle maxClientArea = new Rectangle(0, 0, layer.getWidth(), layer.getHeight());

        layer.setClientAreaProvider(() -> maxClientArea);

        layer.doCommand(new PrintEntireGridCommand());
    }

    /**
     * Open the export result in the matching application.
     *
     * @param exporter
     *            The {@link IExporter} that was used to perform the export.
     *            Needed to access the export result.
     *
     * @since 1.5
     */
    protected void openExport(IExporter exporter) {
        if (this.exportSucceeded
                && this.openResult
                && exporter.getResult() != null
                && exporter.getResult() instanceof File) {
            Program.launch(((File) exporter.getResult()).getAbsolutePath());
        }
    }

    /**
     * Sets the behavior after finishing the export.
     *
     * The default is opening the created export file with the associated
     * application. You can prevent the opening by setting openResult to
     * <code>false</code>.
     *
     * @param openResult
     *            set to <code>true</code> to open the created export file,
     *            <code>false</code> otherwise
     *
     * @since 1.5
     */
    public void setOpenResult(boolean openResult) {
        this.openResult = openResult;
    }

    /**
     * Method that is used to retrieve the {@link OutputStream} to write the
     * export to in a safe way. Any occurring exception will be handled inside.
     *
     * @param exporter
     *            The {@link ILayerExporter} that should be used
     * @return The {@link OutputStream} that is used to write the export to or
     *         <code>null</code> if an error occurs.
     *
     * @since 1.5
     */
    protected OutputStream getOutputStream(IExporter exporter) {
        OutputStream outputStream = null;
        try {
            outputStream = exporter.getOutputStream(this.shell);
        } catch (Exception e) {
            handleExportException(e);
        }
        return outputStream;
    }

    /**
     * Method that is used to handle exceptions that are raised while processing
     * the export.
     *
     * @param e
     *            The exception that should be handled.
     * @since 1.5
     */
    protected void handleExportException(Exception e) {
        LOG.error("Failed to export.", e); //$NON-NLS-1$

        ExceptionDialog.open(
                this.shell,
                Messages.getString("ErrorDialog.title"), //$NON-NLS-1$
                Messages.getString("NatExporter.errorMessagePrefix", e.getLocalizedMessage()), //$NON-NLS-1$
                e);
    }

    /**
     * Enable in-memory pre-rendering. This is necessary in case content
     * painters are used that are configured for content based auto-resizing.
     *
     * @since 1.5
     */
    public void enablePreRendering() {
        this.preRender = true;
    }

    /**
     * Disable in-memory pre-rendering. You should consider to disable
     * pre-rendering if no content painters are used that are configured for
     * content based auto-resizing.
     *
     * @since 1.5
     */
    public void disablePreRendering() {
        this.preRender = false;
    }
}
