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

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Centralises logic for finding/opening sample files
 */
public final class POIDataSamples {

    /**
     * Name of the system property that defined path to the test data.
     */
    public static final String TEST_PROPERTY = "POI.testdata.path";

    private static POIDataSamples _instSlideshow;
    private static POIDataSamples _instSpreadsheet;
    private static POIDataSamples _instDocument;
    private static POIDataSamples _instDiagram;
    private static POIDataSamples _instOpenxml4j;
    private static POIDataSamples _instPOIFS;
    private static POIDataSamples _instDDF;
    private static POIDataSamples _instHMEF;
    private static POIDataSamples _instHPSF;
    private static POIDataSamples _instHPBF;
    private static POIDataSamples _instHSMF;
    private static POIDataSamples _instXmlDSign;

    private File _resolvedDataDir;
    /** <code>true</code> if standard system propery is not set,
     * but the data is available on the test runtime classpath */
    private boolean _sampleDataIsAvaliableOnClassPath;
    private final String _moduleDir;

    /**
     *
     * @param moduleDir   the name of the directory containing the test files
     */
    private POIDataSamples(String moduleDir){
        _moduleDir = moduleDir;
        initialise();
    }

    public static POIDataSamples getSpreadSheetInstance(){
        if(_instSpreadsheet == null) _instSpreadsheet = new POIDataSamples("spreadsheet");
        return _instSpreadsheet;
    }

    public static POIDataSamples getDocumentInstance(){
        if(_instDocument == null) _instDocument = new POIDataSamples("document");
        return _instDocument;
    }

    public static POIDataSamples getSlideShowInstance(){
        if(_instSlideshow == null) _instSlideshow = new POIDataSamples("slideshow");
        return _instSlideshow;
    }

    public static POIDataSamples getDiagramInstance(){
        if(_instOpenxml4j == null) _instOpenxml4j = new POIDataSamples("diagram");
        return _instOpenxml4j;
    }

    public static POIDataSamples getOpenXML4JInstance(){
        if(_instDiagram == null) _instDiagram = new POIDataSamples("openxml4j");
        return _instDiagram;
    }

    public static POIDataSamples getPOIFSInstance(){
        if(_instPOIFS == null) _instPOIFS = new POIDataSamples("poifs");
        return _instPOIFS;
    }

    public static POIDataSamples getDDFInstance(){
        if(_instDDF == null) _instDDF = new POIDataSamples("ddf");
        return _instDDF;
    }

    public static POIDataSamples getHPSFInstance(){
        if(_instHPSF == null) _instHPSF = new POIDataSamples("hpsf");
        return _instHPSF;
    }

    public static POIDataSamples getPublisherInstance(){
        if(_instHPBF == null) _instHPBF = new POIDataSamples("publisher");
        return _instHPBF;
    }

    public static POIDataSamples getHMEFInstance(){
        if(_instHMEF == null) _instHMEF = new POIDataSamples("hmef");
        return _instHMEF;
    }

    public static POIDataSamples getHSMFInstance(){
        if(_instHSMF == null) _instHSMF = new POIDataSamples("hsmf");
        return _instHSMF;
    }

    public static POIDataSamples getXmlDSignInstance(){
        if(_instXmlDSign == null) _instXmlDSign = new POIDataSamples("xmldsign");
        return _instXmlDSign;
    }
    
    /**
     * Opens a sample file from the test data directory
     *
     * @param  sampleFileName the file to open
     * @return an open <tt>InputStream</tt> for the specified sample file
     */
    public InputStream openResourceAsStream(String sampleFileName) {

        if (_sampleDataIsAvaliableOnClassPath) {
            InputStream result = sampleFileName == null ? null :
                    openClasspathResource(sampleFileName);
            if(result == null) {
                throw new RuntimeException("specified test sample file '" + sampleFileName
                        + "' not found on the classpath");
            }
            // wrap to avoid temp warning method about auto-closing input stream
            return new NonSeekableInputStream(result);
        }
        if (_resolvedDataDir == null) {
            throw new RuntimeException("Must set system property '"
                    + TEST_PROPERTY
                    + "' properly before running tests");
        }

        File f = getFile(sampleFileName);
        try {
            return new FileInputStream(f);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param sampleFileName    the name of the test file
     * @return Verifies that the file with the given name exists in the test-data directory
     * @throws RuntimeException if the file was not found
     */
    public File getFile(String sampleFileName) {
        File f = new File(_resolvedDataDir, sampleFileName);
        if (!f.exists()) {
            throw new RuntimeException("Sample file '" + sampleFileName
                    + "' not found in data dir '" + _resolvedDataDir.getAbsolutePath() + "'");
        }
        try {
            if(sampleFileName.length() > 0) {
               String fn = sampleFileName;
               if(fn.indexOf('/') > 0) {
                  fn = fn.substring(fn.indexOf('/')+1);
               }
               if(!fn.equals(f.getCanonicalFile().getName())){
                   throw new RuntimeException("File name is case-sensitive: requested '" + fn
                        + "' but actual file is '" + f.getCanonicalFile().getName() + "'");
               }
            }
        } catch (IOException e){
            throw new RuntimeException(e);
        }
        return f;
    }

    private void initialise() {
        String dataDirName = System.getProperty(TEST_PROPERTY);
        if (dataDirName == null) {
            // check to see if we can just get the resources from the classpath
            InputStream is = openClasspathResource("");
            if (is != null) {
                try {
                    is.close(); // be nice
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                _sampleDataIsAvaliableOnClassPath = true;
                return;
            }

            if(new File("test-data").exists()) {
               dataDirName = "test-data";
            } else {
               throw new RuntimeException("Must set system property '" +
                       TEST_PROPERTY + "' before running tests");
            }
        }
        File dataDir = new File(dataDirName, _moduleDir);
        if (!dataDir.exists()) {
            throw new RuntimeException("Data dir '" + dataDir + "' does not exist");
        }
        // convert to canonical file, to make any subsequent error messages
        // clearer.
        try {
            _resolvedDataDir = dataDir.getCanonicalFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Opens a test sample file from the 'data' sub-package of this class's package.
     *
     * @param  sampleFileName the file to open
     * @return <code>null</code> if the sample file is not deployed on the classpath.
     */
    private InputStream openClasspathResource(String sampleFileName) {
        return getClass().getResourceAsStream("/" + _moduleDir + "/" + sampleFileName);
    }

    private static final class NonSeekableInputStream extends InputStream {

        private final InputStream _is;

        public NonSeekableInputStream(InputStream is) {
            _is = is;
        }

        @Override
        public int read() throws IOException {
            return _is.read();
        }
        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            return _is.read(b, off, len);
        }
        @Override
        public boolean markSupported() {
            return false;
        }
        @Override
        public void close() throws IOException {
            _is.close();
        }
    }

    /**
     * @param  fileName the file to open
     * @return byte array of sample file content from file found in standard test-data directory
     */
    public byte[] readFile(String fileName) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try {
            InputStream fis = openResourceAsStream(fileName);

            byte[] buf = new byte[512];
            while (true) {
                int bytesRead = fis.read(buf);
                if (bytesRead < 1) {
                    break;
                }
                bos.write(buf, 0, bytesRead);
            }
            fis.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return bos.toByteArray();
    }

}
