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