/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
package org.apache.poi.sl.usermodel;

import static org.apache.poi.extractor.ExtractorFactory.OOXML_PACKAGE;
import static org.apache.poi.poifs.crypt.Decryptor.DEFAULT_POIFS_ENTRY;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;

import org.apache.poi.EmptyFileException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

public final class SlideShowFactory {

    private static class Singleton {
        private static final SlideShowFactory INSTANCE = new SlideShowFactory();
    }

    private interface ProviderMethod {
        SlideShow<?,?> create(SlideShowProvider<?,?> prov) throws IOException;
    }

    private final List<SlideShowProvider<?,?>> provider = new ArrayList<>();

    private SlideShowFactory() {
        ClassLoader cl = SlideShowFactory.class.getClassLoader();
        ServiceLoader.load(SlideShowProvider.class, cl).forEach(provider::add);
    }

    /**
     * Create a new empty SlideShow, either XSLF or HSLF depending
     * on the parameter
     *
     * @param XSLF If an XSLFSlideShow or a HSLFSlideShow should be created
     *
     * @return The created SlideShow
     *
     * @throws IOException if an error occurs while creating the objects
     */
    public static SlideShow<?,?> create(boolean XSLF) throws IOException {
        return wp(XSLF ? FileMagic.OOXML : FileMagic.OLE2, SlideShowProvider::create);
    }

    /**
     * Creates a HSLFSlideShow from the given POIFSFileSystem<p>
     *
     * Note that in order to properly release resources the
     * SlideShow should be closed after use.
     *
     * @param fs The {@link POIFSFileSystem} to read the document from
     *
     * @return The created SlideShow
     *
     * @throws IOException if an error occurs while reading the data
     */
    public static SlideShow<?,?> create(POIFSFileSystem fs) throws IOException {
        return create(fs, null);
    }

    /**
     * Creates a SlideShow from the given POIFSFileSystem, which may
     *  be password protected
     *
     *  @param fs The {@link POIFSFileSystem} to read the document from
     *  @param password The password that should be used or null if no password is necessary.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     */
    private static SlideShow<?,?> create(final POIFSFileSystem fs, String password) throws IOException {
        return create(fs.getRoot(), password);
    }


    /**
     * Creates a SlideShow from the given DirectoryNode.
     *
     * @param root The {@link DirectoryNode} to start reading the document from
     *
     * @return The created SlideShow
     *
     * @throws IOException if an error occurs while reading the data
     */
    public static SlideShow<?,?> create(final DirectoryNode root) throws IOException {
        return create(root, null);
    }


    /**
     * Creates a SlideShow from the given DirectoryNode, which may
     * be password protected
     *
     * @param root The {@link DirectoryNode} to start reading the document from
     * @param password The password that should be used or null if no password is necessary.
     *
     * @return The created SlideShow
     *
     * @throws IOException if an error occurs while reading the data
     */
    public static SlideShow<?,?> create(final DirectoryNode root, String password) throws IOException {
        // Encrypted OOXML files go inside OLE2 containers, is this one?
        if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE)) {
            return wp(FileMagic.OOXML, w -> w.create(root, password));
        } else {
            return wp(FileMagic.OLE2, w ->  w.create(root, password));
        }
    }

    /**
     * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
     *  the given InputStream.
     *
     * <p>Your input stream MUST either support mark/reset, or
     *  be wrapped as a {@link BufferedInputStream}!
     *  Note that using an {@link InputStream} has a higher memory footprint
     *  than using a {@link File}.</p>
     *
     * <p>Note that in order to properly release resources the
     *  SlideShow should be closed after use. Note also that loading
     *  from an InputStream requires more memory than loading
     *  from a File, so prefer {@link #create(File)} where possible.
     *
     *  @param inp The {@link InputStream} to read data from.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     *  @throws EncryptedDocumentException If the SlideShow given is password protected
     */
    public static SlideShow<?,?> create(InputStream inp) throws IOException, EncryptedDocumentException {
        return create(inp, null);
    }

    /**
     * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
     *  the given InputStream, which may be password protected.
     *
     * <p>Your input stream MUST either support mark/reset, or
     *  be wrapped as a {@link BufferedInputStream}!
     *  Note that using an {@link InputStream} has a higher memory footprint
     *  than using a {@link File}.</p>
     *
     * <p>Note that in order to properly release resources the
     *  SlideShow should be closed after use. Note also that loading
     *  from an InputStream requires more memory than loading
     *  from a File, so prefer {@link #create(File)} where possible.</p>
     *
     *  @param inp The {@link InputStream} to read data from.
     *  @param password The password that should be used or null if no password is necessary.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
     */
    public static SlideShow<?,?> create(InputStream inp, String password) throws IOException, EncryptedDocumentException {
        InputStream is = FileMagic.prepareToCheckMagic(inp);
        byte[] emptyFileCheck = new byte[1];
        is.mark(emptyFileCheck.length);
        if (is.read(emptyFileCheck) < emptyFileCheck.length) {
            throw new EmptyFileException();
        }
        is.reset();

        final FileMagic fm = FileMagic.valueOf(is);
        if (FileMagic.OOXML == fm) {
            return wp(fm, w -> w.create(is));
        }

        if (FileMagic.OLE2 != fm) {
            throw new IOException("Can't open SlideShow - unsupported file type: "+fm);
        }

        POIFSFileSystem poifs = new POIFSFileSystem(is);
        DirectoryNode root = poifs.getRoot();
        boolean isOOXML = root.hasEntry(DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE);

        return wp(isOOXML ? FileMagic.OOXML : fm, w -> w.create(poifs.getRoot(), password));
    }

    /**
     * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
     *  the given File, which must exist and be readable.
     * <p>Note that in order to properly release resources the
     *  SlideShow should be closed after use.
     *
     *  @param file The file to read data from.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     *  @throws EncryptedDocumentException If the SlideShow given is password protected
     */
    public static SlideShow<?,?> create(File file) throws IOException, EncryptedDocumentException {
        return create(file, null);
    }

    /**
     * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
     *  the given File, which must exist and be readable, and
     *  may be password protected
     * <p>Note that in order to properly release resources the
     *  SlideShow should be closed after use.
     *
     *  @param file The file to read data from.
     *  @param password The password that should be used or null if no password is necessary.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
     */
    public static SlideShow<?,?> create(File file, String password) throws IOException, EncryptedDocumentException {
        return create(file, password, false);
    }

    /**
     * Creates the appropriate HSLFSlideShow / XSLFSlideShow from
     *  the given File, which must exist and be readable, and
     *  may be password protected
     * <p>Note that in order to properly release resources the
     *  SlideShow should be closed after use.
     *
     *  @param file The file to read data from.
     *  @param password The password that should be used or null if no password is necessary.
     *  @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back
     *      changes when the document is closed.
     *
     *  @return The created SlideShow
     *
     *  @throws IOException if an error occurs while reading the data
     *  @throws EncryptedDocumentException If the wrong password is given for a protected file
     */
    public static SlideShow<?,?> create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException {
        if (!file.exists()) {
            throw new FileNotFoundException(file.toString());
        }

        if (file.length() == 0) {
            throw new EmptyFileException(file);
        }

        FileMagic fm = FileMagic.valueOf(file);
        if (fm == FileMagic.OOXML) {
            return wp(fm, w -> w.create(file, password, readOnly));
        } else if (fm == FileMagic.OLE2) {
            final boolean ooxmlEnc;
            try (POIFSFileSystem fs = new POIFSFileSystem(file, true)) {
                DirectoryNode root = fs.getRoot();
                ooxmlEnc = root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE);
            }
            return wp(ooxmlEnc ? FileMagic.OOXML : fm, w -> w.create(file, password, readOnly));
        }

        return null;
    }



    private static SlideShow<?,?> wp(FileMagic fm, SlideShowFactory.ProviderMethod fun) throws IOException {

        for (SlideShowProvider<?,?> prov : SlideShowFactory.Singleton.INSTANCE.provider) {
            if (prov.accepts(fm)) {
                return fun.create(prov);
            }
        }
        throw new IOException("Your InputStream was neither an OLE2 stream, nor an OOXML stream " +
                                      "or you haven't provide the poi-ooxml*.jar in the classpath/modulepath - FileMagic: "+fm);
    }

    public static void addProvider(SlideShowProvider<?,?> provider){
        Singleton.INSTANCE.provider.add(provider);
    }

    public static void removeProvider(Class<? extends SlideShowProvider<?,?>> provider){
        Singleton.INSTANCE.provider.removeIf(p -> p.getClass().isAssignableFrom(provider));
    }
}
