/* ====================================================================
   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 java.io.OutputStream;

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(R wb, String testName)}.  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
     */
    public static <R extends Workbook> File writeOut(R wb, String testName) throws IOException {
        final String testOutputDir = System.getProperty(TEST_OUTPUT_DIR);
        final File file;
        if (testOutputDir != null) {
            file = new File(testOutputDir, testName + ".xlsx");
        }
        else {
            file = TempFile.createTempFile(testName, ".xlsx");
        }
        if (file.exists()) {
            file.delete();
        }
        final OutputStream out = new FileOutputStream(file);
        try {
            wb.write(out);
        } finally {
            out.close();
        }
        return file;
    }
    
    /**
     * Write out workbook <code>wb</code> to a memory buffer
     *
     * @param wb the workbook to write
     * @return the memory buffer
     * @throws IOException
     */
    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
     * @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 IOException
     */
    public static <R extends Workbook> ByteArrayOutputStream writeOutAndClose(R wb) {
        try {
            ByteArrayOutputStream out = writeOut(wb);
            // Do not close the workbook if there was a problem writing the workbook
            wb.close();
            return out;
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 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
     */
    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 
        file.delete();
        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
     */
    public static XSSFWorkbook readBack(File file) throws IOException {
        InputStream in = new FileInputStream(file);
        try {
            return new XSSFWorkbook(in);
        }
        finally {
            in.close();
        }
    }
    
    /**
     * Read back a workbook that was written out to a memory buffer with
     * {@link #writeOut(Workbook)} or {@link #writeOutAndClose(Workbook)}.
     *
     * @param file the workbook file to read
     * @return the read back workbook
     * @throws IOException
     */
    public static XSSFWorkbook readBack(ByteArrayOutputStream out) throws IOException {
        InputStream is = new ByteArrayInputStream(out.toByteArray());
        out.close();
        try {
            return new XSSFWorkbook(is);
        }
        finally {
            is.close();
        }
    }
    
    /**
     * 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);
            }
        }
    }
}
