/* ====================================================================
   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.ss;

import static org.junit.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileNotFoundException;

import org.apache.poi.EmptyFileException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.junit.Test;

public final class TestWorkbookFactory {
    private static final String xls = "SampleSS.xls";
    private static final String xlsx = "SampleSS.xlsx";
    private static final String[] xls_prot = new String[] {"password.xls", "password"};
    private static final String[] xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"};
    private static final String txt = "SampleSS.txt";
    
    private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class);
    
    /**
     * Closes the sample workbook read in from filename.
     * Throws an exception if closing the workbook results in the file on disk getting modified.
     *
     * @param filename the sample workbook to read in
     * @param wb the workbook to close
     * @throws IOException
     */
    private static void assertCloseDoesNotModifyFile(String filename, Workbook wb) throws IOException {
        final byte[] before = HSSFTestDataSamples.getTestDataFileContent(filename);
        // FIXME: replace with wb.close() when bug 58779 is resolved
        closeOrRevert(wb);
        final byte[] after = HSSFTestDataSamples.getTestDataFileContent(filename);
        assertArrayEquals(filename + " sample file was modified as a result of closing the workbook",
                before, after);
    }
    
    /**
     * bug 58779: Closing an XSSFWorkbook that was created with WorkbookFactory modifies the file
     * FIXME: replace this method with wb.close() when bug 58779 is resolved.
     *
     * @param wb the workbook to close or revert
     */
    private static void closeOrRevert(Workbook wb) throws IOException {
        if (wb instanceof HSSFWorkbook) {
            wb.close();
        }
        else if (wb instanceof XSSFWorkbook) {
            final XSSFWorkbook xwb = (XSSFWorkbook) wb;
            if (PackageAccess.READ == xwb.getPackage().getPackageAccess()) {
                xwb.close();
            }
            else {
                // TODO: close() re-writes the sample-file?! Resort to revert() for now to close file handle...
                LOGGER.log(POILogger.WARN,
                        "reverting XSSFWorkbook rather than closing it to avoid close() modifying the file on disk. " +
                        "Refer to bug 58779.");
                xwb.getPackage().revert();
            }
        } else {
            throw new RuntimeException("Unsupported workbook type");
        }
    }

    @Test
    public void testCreateNative() throws Exception {
        Workbook wb;

        // POIFS -> hssf
        wb = WorkbookFactory.create(
                new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream(xls))
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        // Package -> xssf
        wb = WorkbookFactory.create(
                OPCPackage.open(
                        HSSFTestDataSamples.openSampleFileStream(xlsx))
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);
    }

    @Test
    public void testCreateReadOnly() throws Exception {
        Workbook wb;

        // POIFS -> hssf
        wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xls), null, true);
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        // Package -> xssf
        wb = WorkbookFactory.create(HSSFTestDataSamples.getSampleFile(xlsx), null, true);
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);
    }

    /**
     * Creates the appropriate kind of Workbook, but
     *  checking the mime magic at the start of the
     *  InputStream, then creating what's required.
     */
    @Test
    public void testCreateGeneric() throws Exception {
        Workbook wb;

        // InputStream -> either
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xls)
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xlsx)
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);

        // File -> either
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xls)
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xlsx)
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);

        // Invalid type -> exception
        final byte[] before = HSSFTestDataSamples.getTestDataFileContent(txt);
        try {
            InputStream stream = HSSFTestDataSamples.openSampleFileStream(txt);
            try {
                wb = WorkbookFactory.create(stream);
            } finally {
                stream.close();
            }
            fail();
        } catch(InvalidFormatException e) {
            // Good
        }
        final byte[] after = HSSFTestDataSamples.getTestDataFileContent(txt);
        assertArrayEquals("Invalid type file was modified after trying to open the file as a spreadsheet",
                before, after);
    }

    /**
     * Check that the overloaded stream methods which take passwords work properly
     */
    @Test
    public void testCreateWithPasswordFromStream() throws Exception {
        Workbook wb;


        // Unprotected, no password given, opens normally
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xls), null
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xlsx), null
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);


        // Unprotected, wrong password, opens normally
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xls), "wrong"
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xlsx), "wrong"
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);


        // Protected, correct password, opens fine
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1]
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls_prot[0], wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1]
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx_prot[0], wb);


        // Protected, wrong password, throws Exception
        try {
            wb = WorkbookFactory.create(
                    HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), "wrong"
            );
            assertCloseDoesNotModifyFile(xls_prot[0], wb);
            fail("Shouldn't be able to open with the wrong password");
        } catch (EncryptedDocumentException e) {}

        try {
            wb = WorkbookFactory.create(
                    HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), "wrong"
            );
            assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
            fail("Shouldn't be able to open with the wrong password");
        } catch (EncryptedDocumentException e) {}
    }

    /**
     * Check that the overloaded file methods which take passwords work properly
     */
    @Test
    public void testCreateWithPasswordFromFile() throws Exception {
        Workbook wb;

        // Unprotected, no password given, opens normally
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xls), null
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xlsx), null
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);

        // Unprotected, wrong password, opens normally
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xls), "wrong"
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls, wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xlsx), "wrong"
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertCloseDoesNotModifyFile(xlsx, wb);

        // Protected, correct password, opens fine
        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1]
        );
        assertNotNull(wb);
        assertTrue(wb instanceof HSSFWorkbook);
        assertCloseDoesNotModifyFile(xls_prot[0], wb);

        wb = WorkbookFactory.create(
                HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1]
        );
        assertNotNull(wb);
        assertTrue(wb instanceof XSSFWorkbook);
        assertTrue(wb.getNumberOfSheets() > 0);
        assertNotNull(wb.getSheetAt(0));
        assertNotNull(wb.getSheetAt(0).getRow(0));
        assertCloseDoesNotModifyFile(xlsx_prot[0], wb);

        // Protected, wrong password, throws Exception
        try {
            wb = WorkbookFactory.create(
                    HSSFTestDataSamples.getSampleFile(xls_prot[0]), "wrong"
            );
            assertCloseDoesNotModifyFile(xls_prot[0], wb);
            fail("Shouldn't be able to open with the wrong password");
        } catch (EncryptedDocumentException e) {
            // expected here
        }

        try {
            wb = WorkbookFactory.create(
                    HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), "wrong"
            );
            assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
            fail("Shouldn't be able to open with the wrong password");
        } catch (EncryptedDocumentException e) {
            // expected here
        }
    }
    
    /**
     * Check that a helpful exception is given on an empty input stream
     */
    @Test
    public void testEmptyInputStream() throws Exception {
        InputStream emptyStream = new ByteArrayInputStream(new byte[0]);
        try {
            WorkbookFactory.create(emptyStream);
            fail("Shouldn't be able to create for an empty stream");
        } catch (final EmptyFileException expected) {}
    }
    
    /**
     * Check that a helpful exception is given on an empty file
     */
    @Test
    public void testEmptyFile() throws Exception {
        File emptyFile = TempFile.createTempFile("empty", ".poi");
        try {
            WorkbookFactory.create(emptyFile);
            fail("Shouldn't be able to create for an empty file");
        } catch (final EmptyFileException expected) {}
        emptyFile.delete();
    }

    /**
      * Check that a helpful exception is raised on a non-existing file
      */
    @Test
    public void testNonExistantFile() throws Exception {
        File nonExistantFile = new File("notExistantFile");
        assertFalse(nonExistantFile.exists());

        try {
            WorkbookFactory.create(nonExistantFile, "password", true);
            fail("Should not be able to create for a non-existant file");
        } catch (final FileNotFoundException e) {
            // expected
        }
    }

}
