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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Centralises logic for finding/opening sample files in the test-data/spreadsheet folder.
 *
 * @author Josh Micich
 */
public class XSSFTestDataSamples {
    /**
     * Used by {@link #writeOutAndReadBack(Workbook, String)}.  If a
     * value is set for this in the System Properties, the xlsx file
     * will be written out to that directory.
     */
    public static final String TEST_OUTPUT_DIR = "poi.test.xssf.output.dir";

    public static File getSampleFile(String sampleFileName) {
        return HSSFTestDataSamples.getSampleFile(sampleFileName);
    }
    public static OPCPackage openSamplePackage(String sampleName) {
        try {
            return OPCPackage.open(HSSFTestDataSamples.openSampleFileStream(sampleName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static XSSFWorkbook openSampleWorkbook(String sampleName) {
        InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleName);
        try {
            return new XSSFWorkbook(is);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Write out workbook <code>wb</code> to {@link #TEST_OUTPUT_DIR}/testName.xlsx
     * (or create a temporary file if <code>TEST_OUTPUT_DIR</code> is not defined).
     *
     * @param wb the workbook to write
     * @param testName a fragment of the filename
     * @return the location where the workbook was saved
     * @throws IOException If writing the file fails
     */
    public static <R extends Workbook> File writeOut(R wb, String testName) throws IOException {
        final File file = getOutputFile(testName);
        writeOut(wb, file);
        return file;
    }

    private static <R extends Workbook> void writeOut(R wb, File file) throws IOException {
        try (FileOutputStream out = new FileOutputStream(file)) {
            wb.write(out);
        }
    }

    // Anticipates the location of where a workbook will be written to
    // Note that if TEST_OUTPUT_DIR is not set, this will create temporary files
    // with unique names. Subsequent calls with the same argument may return a different file.
    // Gets a test data sample file, deleting the file if it exists.
    // This is used in preparation for writing a workbook out to the returned output file.
    // testName is a filename fragment and should not include the extension
    private static File getOutputFile(String testName) throws IOException {
        final String testOutputDir = System.getProperty(TEST_OUTPUT_DIR);
        final File file;
        if (testOutputDir != null) {
            // In case user provided testName with a file extension, don't repeat the file extension a second time
            final String testNameWithExtension = testName.endsWith(".xlsx") ? testName : testName + ".xlsx";
            // FIXME: may want to defer to the TempFile with a persistent file creation strategy to the test output dir
            // This would add the random value in the middle of the filename so that test runs wouldn't overwrite files
            file = new File(testOutputDir, testNameWithExtension);
        }
        else {
            file = TempFile.createTempFile(testName, ".xlsx");
        }
        if (file.exists()) {
            if(!file.delete()) {
                throw new IOException("Could not delete file " + file);
            }
        }
        return file;
    }

    /**
     * Write out workbook <code>wb</code> to a memory buffer
     *
     * @param wb the workbook to write
     * @return the memory buffer
     * @throws IOException If writing the file fails
     */
    public static <R extends Workbook> ByteArrayOutputStream writeOut(R wb) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream(8192);
        wb.write(out);
        return out;
    }

    /**
     * Write out the workbook then closes the workbook.
     * This should be used when there is insufficient memory to have
     * both workbooks open.
     *
     * Make sure there are no references to any objects in the workbook
     * so that garbage collection may free the workbook.
     *
     * After calling this method, null the reference to <code>wb</code>,
     * then call {@link #readBack(File)} or {@link #readBackAndDelete(File)} to re-read the file.
     *
     * Alternatively, use {@link #writeOutAndClose(Workbook)} to use a ByteArrayOutputStream/ByteArrayInputStream
     * to avoid creating a temporary file. However, this may complicate the calling
     * code to avoid having the workbook, BAOS, and BAIS open at the same time.
     *
     * @param wb The workbook to write out, it is closed after the call.
     * @param testName file name to be used to write to a file. This file will be cleaned up by a call to readBack(String)
     * @return workbook location
     * @throws RuntimeException if {@link #TEST_OUTPUT_DIR} System property is not set
     */
    public static <R extends Workbook> File writeOutAndClose(R wb, String testName) {
        try {
            File file = writeOut(wb, testName);
            // Do not close the workbook if there was a problem writing the workbook
            wb.close();
            return file;
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * Write out workbook <code>wb</code> to a memory buffer,
     * then close the workbook
     *
     * @param wb the workbook to write
     * @return the memory buffer
     * @throws RuntimeException If writing the file fails
     */
    public static <R extends Workbook> ByteArrayOutputStream writeOutAndClose(R wb) throws IOException {
        ByteArrayOutputStream out = writeOut(wb);
        // Do not close the workbook if there was a problem writing the workbook
        wb.close();
        return out;
    }

    /**
     * Read back a workbook that was written out to a file with
     * {@link #writeOut(Workbook, String))} or {@link #writeOutAndClose(Workbook, String)}.
     * Deletes the file after reading back the file.
     * Does not delete the file if an exception is raised.
     *
     * @param file the workbook file to read and delete
     * @return the read back workbook
     * @throws IOException If reading or deleting the file fails
     */
    public static XSSFWorkbook readBackAndDelete(File file) throws IOException {
        XSSFWorkbook wb = readBack(file);
        // do not delete the file if there's an error--might be helpful for debugging
        if(!file.delete()) {
            throw new IOException("Could not delete file " + file + " after reading");
        }
        return wb;
    }

    /**
     * Read back a workbook that was written out to a file with
     * {@link #writeOut(Workbook, String)} or {@link #writeOutAndClose(Workbook, String)}.
     *
     * @param file the workbook file to read
     * @return the read back workbook
     * @throws IOException If reading the file fails
     */
    public static XSSFWorkbook readBack(File file) throws IOException {
        try (InputStream in = new FileInputStream(file)) {
            return new XSSFWorkbook(in);
        }
    }

    /**
     * Read back a workbook that was written out to a memory buffer with
     * {@link #writeOut(Workbook)} or {@link #writeOutAndClose(Workbook)}.
     *
     * @param out the output stream to read back from
     * @return the read back workbook
     * @throws IOException If reading the file fails
     */
    public static XSSFWorkbook readBack(ByteArrayOutputStream out) throws IOException {
        try (InputStream is = new ByteArrayInputStream(out.toByteArray())) {
            out.close();
            return new XSSFWorkbook(is);
        }
    }

    /**
     * Write out and read back using a memory buffer to avoid disk I/O.
     * If there is not enough memory to have two workbooks open at the same time,
     * consider using:
     *
     * Workbook wb = new XSSFWorkbook();
     * String testName = "example";
     *
     * <code>
     * File file = writeOutAndClose(wb, testName);
     * // clear all references that would prevent the workbook from getting garbage collected
     * wb = null;
     * Workbook wbBack = readBackAndDelete(file);
     * </code>
     *
     * @param wb the workbook to write out
     * @return the read back workbook
     */
    public static <R extends Workbook> R writeOutAndReadBack(R wb) {
        Workbook result;
        try {
            result = readBack(writeOut(wb));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        @SuppressWarnings("unchecked")
        R r = (R) result;
        return r;
    }

    /**
     * Write out, close, and read back the workbook using a memory buffer to avoid disk I/O.
     *
     * @param wb the workbook to write out and close
     * @return the read back workbook
     */
    public static <R extends Workbook> R writeOutCloseAndReadBack(R wb) {
        Workbook result;
        try {
            result = readBack(writeOutAndClose(wb));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        @SuppressWarnings("unchecked")
        R r = (R) result;
        return r;

    }

    /**
     * Writes the Workbook either into a file or into a byte array, depending on presence of
     * the system property {@value #TEST_OUTPUT_DIR}, and reads it in a new instance of the Workbook back.
     * If TEST_OUTPUT_DIR is set, the file will NOT be deleted at the end of this function.
     * @param wb workbook to write
     * @param testName file name to be used if writing into a file. The old file with the same name will be overridden.
     * @return new instance read from the stream written by the wb parameter.
     */

    public static <R extends Workbook> R writeOutAndReadBack(R wb, String testName) {
        if (System.getProperty(TEST_OUTPUT_DIR) == null) {
            return writeOutAndReadBack(wb);
        } else {
            try {
                Workbook result = readBack(writeOut(wb, testName));
                @SuppressWarnings("unchecked")
                R r = (R) result;
                return r;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
