/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw;

import java.io.File;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import junit.framework.TestCase;

import net.sf.jaxodraw.util.JaxoUtils;


/** Common base class for tests. */
public class AbstractJaxoBaseTest extends TestCase {

    private final String baseDir;
    private final String testOutputDir;

    /**
     * Asserts that two floats are equal within 1%.
     *
     * @param expected expected
     * @param actual actual
     * @see net.sf.jaxodraw.util.JaxoUtils#equal(float,float,float)
     */
    public static void assertEquals(float expected, float actual) {
        assertEquals("", expected, actual);
    }

    /**
     * Asserts that two floats are equal within 1%.
     *
     * @param message a message
     * @param expected expected
     * @param actual actual
     * @see net.sf.jaxodraw.util.JaxoUtils#equal(float,float,float)
     */
    public static void assertEquals(String message, float expected, float actual) {
        assertTrue(message + " Expected: " + expected + ", but got: " + actual,
                JaxoUtils.equal(expected, actual, 0.01f));
    }

    /**
     * Assert that two arrays are equivalent.
     *
     * @param expected expected.
     * @param actual actual.
     *
     * @see #assertEquivalentArrays(java.lang.String,java.lang.Object[],java.lang.Object[])
     */
    public static void assertEquivalentArrays(Object[] expected, Object[] actual) {
        assertEquivalentArrays("", expected, actual);
    }

    /**
     * Assert that two arrays are equivalent.
     *
     * @param message a message.
     * @param expected expected result.
     * @param actual actual result.
     *
     * @see JaxoUtils#equivalent(java.lang.Object[],java.lang.Object[])
     */
    public static void assertEquivalentArrays(String message,
            Object[] expected, Object[] actual) {
        assertTrue(message + " Expected: " + JaxoUtils.toString(expected)
                + ", but got: " + JaxoUtils.toString(actual),
                JaxoUtils.equivalent(actual, expected));
    }

    /**
     * Assert that two arrays are equal.
     *
     * @param expected expected result.
     * @param actual actual result.
     *
     * @see #assertEqualArrays(java.lang.String,java.lang.Object[],java.lang.Object[])
     */
    public static void assertEqualArrays(Object[] expected, Object[] actual) {
        assertEqualArrays("", expected, actual);
    }

    /**
     * Assert that two arrays are equal.
     *
     * @param message a message.
     * @param expected expected result.
     * @param actual actual result.
     *
     * @see JaxoUtils#equals(java.lang.Object[],java.lang.Object[])
     */
    public static void assertEqualArrays(String message, Object[] expected, Object[] actual) {
        assertTrue(message + " Expected: " + JaxoUtils.toString(expected)
                + ", but got: " + JaxoUtils.toString(actual),
                JaxoUtils.equals(actual, expected));
    }

    /** Protected constructor. All implementing classes need to provide
     * a same-argument constructor and call super(testName).
     * @param testName The name of this test.
     */
    protected AbstractJaxoBaseTest(String testName) {
        super(testName);
        this.baseDir = getBasedir();
        this.testOutputDir = baseDir + "test-output/";
    }

    /** Return a file for writing test results. If the file exists already,
     * it will be deleted, if this fails, the test stops.
     * @param base The directory base where the output file will be placed.
     * @param fileName The name of the output file.
     * @return An output File.
     */
    protected File getOutputFile(String base, String fileName) {
        File outputDirectory = new File(testOutputDir + base);

        if (!outputDirectory.exists()) {
            outputDirectory.mkdirs();
        }

        File outputFile = new File(outputDirectory, fileName);

        if (outputFile.exists()) {
            outputFile.delete();
        }

        assertFalse("Output file exists!", outputFile.exists());

        return outputFile;
    }

    /** Return a resource file for reading.
     * This will fail if the file does not exist.
     * @param base The directory base where the input file is placed
     * within the test-resources folder.
     * @param fileName The name of the output file.
     * @return A resource File.
     */
    protected File getResourceFile(String base, String fileName) {
        File resourceFile = new File(baseDir + base, fileName);

        if (!resourceFile.exists()) {
            fail("Resource not found: " + baseDir + base + fileName);
        }

        return resourceFile;
    }

      //
     // private
    //

     private String getBasedir() {
        URL url  = this.getClass().getResource("/");
        File base;

        try {
            base = new File(new URI(url.toString()));
        } catch (URISyntaxException e) {
            base = new File(url.getPath());
        }

        return base.getAbsolutePath() + "/";
    }

}
