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


import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.tools.ant.DirectoryScanner;
import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.opentest4j.AssertionFailedError;

/**
 *  This is an integration test which performs various actions on all stored test-files and tries
 *  to reveal problems which are introduced, but not covered (yet) by unit tests.
 *
 *  This test looks for any file under the test-data directory and tries to do some useful
 *  processing with it based on it's type.
 *
 *  The test is implemented as a junit {@link ParameterizedTest} test, which leads
 *  to one test-method call for each file (currently around 950 files are handled).
 *
 *  There is a a mapping of extension to implementations of the interface
 *  {@link FileHandler} which defines how the file is loaded and which actions are
 *  tried with the file.
 *
 *  The test can be expanded by adding more actions to the FileHandlers, this automatically
 *  applies the action to any such file in our test-data repository.
 *
 *  There is also a list of files that should actually fail.
 *
 *  Note: It is also a test-failure if a file that is expected to fail now actually works,
 *  i.e. if a bug was fixed in POI itself, the file should be removed from the expected-failures
 *  here as well! This is to ensure that files that should not work really do not work, e.g.
 *  that we do not remove expected sanity checks.
 */
// also need to set JVM parameter: -Djunit.jupiter.execution.parallel.enabled=true
@Execution(ExecutionMode.CONCURRENT)
public class TestAllFiles {
    private static final String DEFAULT_TEST_DATA_PATH = "test-data";
    public static final File ROOT_DIR = new File(System.getProperty("POI.testdata.path", DEFAULT_TEST_DATA_PATH));

    public static final String[] SCAN_EXCLUDES = {
        "**/.svn/**",
        "lost+found",
        "**/.git/**",
    };

    public static Stream<Arguments> allfiles(String testName) throws IOException {
        StressMap sm = new StressMap();
        sm.load(new File(ROOT_DIR, "spreadsheet/stress.xls"));

        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir(ROOT_DIR);
        scanner.setExcludes(SCAN_EXCLUDES);

        scanner.scan();

        final List<Arguments> result = new ArrayList<>(100);
        for (String file : scanner.getIncludedFiles()) {
            for (FileHandlerKnown handler : sm.getHandler(file)) {
                ExcInfo info1 = sm.getExcInfo(file, testName, handler);
                if (info1 == null || info1.isValid(testName, handler.name())) {
                    result.add(Arguments.of(
                        file,
                        handler,
                        (info1 != null) ? info1.getPassword() : null,
                        (info1 != null) ? info1.getExClazz() : null,
                        (info1 != null) ? info1.getExMessage() : null
                    ));
                }
            }
        }

        return result.stream();
    }

    public static Stream<Arguments> extractFiles() throws IOException {
        return allfiles("extract");
    }

    @ParameterizedTest(name = "#{index} {0} {1}")
    @MethodSource("extractFiles")
    void handleExtracting(String file, FileHandlerKnown handler, String password, Class<? extends Throwable> exClass, String exMessage) throws IOException {
        System.out.println("Running extractFiles on "+file);
        FileHandler fileHandler = handler.fileHandler.get();
        assertNotNull(fileHandler, "Did not find a handler for file " + file);
        Executable exec = () -> fileHandler.handleExtracting(new File(ROOT_DIR, file));
        verify(file, exec, exClass, exMessage, password);
    }

    public static Stream<Arguments> handleFiles() throws IOException {
        return allfiles("handle");
    }

    @ParameterizedTest(name = "#{index} {0} {1}")
    @MethodSource("handleFiles")
    void handleFile(String file, FileHandlerKnown handler, String password, Class<? extends Throwable> exClass, String exMessage) throws IOException {
        System.out.println("Running handleFiles on "+file);
        FileHandler fileHandler = handler.fileHandler.get();
        assertNotNull(fileHandler, "Did not find a handler for file " + file);
        try (InputStream stream = new BufferedInputStream(new FileInputStream(new File(ROOT_DIR, file)), 64 * 1024)) {
            Executable exec = () -> fileHandler.handleFile(stream, file);
            verify(file, exec, exClass, exMessage, password);
        }
    }

    public static Stream<Arguments> handleAdditionals() throws IOException {
        return allfiles("additional");
    }

    @ParameterizedTest(name = "#{index} {0} {1}")
    @MethodSource("handleAdditionals")
    void handleAdditional(String file, FileHandlerKnown handler, String password, Class<? extends Throwable> exClass, String exMessage) {
        System.out.println("Running additionals on "+file);
        FileHandler fileHandler = handler.fileHandler.get();
        assertNotNull(fileHandler, "Did not find a handler for file " + file);
        Executable exec = () -> fileHandler.handleAdditional(new File(ROOT_DIR, file));
        verify(file, exec, exClass, exMessage, password);
    }

    @SuppressWarnings("unchecked")
    private static void verify(String file, Executable exec, Class<? extends Throwable> exClass, String exMessage, String password) {
        final String errPrefix = file + " - failed. ";
        // this also removes the password for non encrypted files
        Biff8EncryptionKey.setCurrentUserPassword(password);
        if (exClass != null && AssertionFailedError.class.isAssignableFrom(exClass)) {
            try {
                exec.execute();
                fail(errPrefix + "Expected failed assertion");
            } catch (AssertionFailedError e) {
                String actMsg = pathReplace(e.getMessage());
                assertEquals(exMessage, actMsg, errPrefix);
            } catch (Throwable e) {
                fail(errPrefix + "Unexpected exception", e);
            }
        } else if (exClass != null) {
            Exception e = assertThrows((Class<? extends Exception>)exClass, exec);
            String actMsg = pathReplace(e.getMessage());
            if (NullPointerException.class.isAssignableFrom(exClass)) {
                if (actMsg != null) {
                    assertTrue(actMsg.contains(exMessage), errPrefix + "Message: "+actMsg+" - didn't contain: "+exMessage);
                }
            } else {
                assertNotNull(actMsg, errPrefix);
                assertTrue(actMsg.contains(exMessage), errPrefix + "Message: "+actMsg+" - didn't contain: "+exMessage);
            }
        } else {
            assertDoesNotThrow(exec, errPrefix);
        }
    }

    private static String pathReplace(String msg) {
        if (msg == null) return null;

        // Windows path replacement
        msg = msg.replace('\\', '/');

        // Adjust file paths to remove unwanted file path info.
        int filePathIndex = msg.indexOf(ROOT_DIR.toString());
        if (filePathIndex > 0) {
            int testDataDirectoryIndex = msg.indexOf(DEFAULT_TEST_DATA_PATH);
            msg = msg.substring(0, filePathIndex) + msg.substring(testDataDirectoryIndex);
        }

        return msg;
    }
}
