package org.apache.velocity.test;

/*
 * 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.
 */

import junit.framework.TestCase;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
import org.apache.velocity.runtime.resource.util.StringResourceRepository;
import org.apache.velocity.test.misc.TestLogger;
import org.apache.velocity.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

/**
 * Base test case that provides utility methods for
 * the rest of the tests.
 *
 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 * @author Nathan Bubna
 * @version $Id$
 */
public abstract class BaseTestCase extends TestCase implements TemplateTestBase
{
    protected VelocityEngine engine;
    protected VelocityContext context;
    protected boolean DEBUG = false;
    protected TestLogger log;
    protected String stringRepoName = "string.repo";

    public BaseTestCase(String name)
    {
        super(name);

        // if we're just running one case, then have DEBUG
        // automatically set to true
        String test = System.getProperty("test");
        if (test != null)
        {
            DEBUG = test.equals(getClass().getSimpleName());
        }
    }

    protected void setUp() throws Exception
    {
        engine = new VelocityEngine();

        //by default, make the engine's log output go to the test-report
        log = new TestLogger(false, false);
        engine.setProperty(RuntimeConstants.RUNTIME_LOG_INSTANCE, log);

        // use string resource loader by default, instead of file
        engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file,string");
        engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName());
        engine.addProperty("string.resource.loader.repository.name", stringRepoName);
        engine.addProperty("string.resource.loader.repository.static", "false");

        setUpEngine(engine);

        context = new VelocityContext();
        setUpContext(context);
    }

    protected void setUpEngine(VelocityEngine engine)
    {
        // extension hook
    }

    protected void setUpContext(VelocityContext context)
    {
        // extension hook
    }

    protected StringResourceRepository getStringRepository()
    {
        StringResourceRepository repo =
            (StringResourceRepository)engine.getApplicationAttribute(stringRepoName);
        if (repo == null)
        {
            engine.init();
            repo =
                (StringResourceRepository)engine.getApplicationAttribute(stringRepoName);
        }
        return repo;
    }

    protected void addTemplate(String name, String template)
    {
        info("Template '"+name+"':  "+template);
        getStringRepository().putStringResource(name, template);
    }

    protected void removeTemplate(String name)
    {
        info("Removed: '"+name+"'");
        getStringRepository().removeStringResource(name);
    }

    public void tearDown()
    {
        engine = null;
        context = null;
    }

    protected void info(String msg)
    {
        info(msg, null);
    }

    protected void info(String msg, Throwable t)
    {
        if (DEBUG)
        {
            try
            {
                if (engine == null)
                {
                    Velocity.getLog().info(msg, t);
                }
                else
                {
                    engine.getLog().info(msg, t);
                }
            }
            catch (Throwable t2)
            {
                System.out.println("Failed to log: "+msg+(t!=null?" - "+t: ""));
                System.out.println("Cause: "+t2);
                t2.printStackTrace();
            }
        }
    }

    public void testBase()
    {
        if (DEBUG && engine != null)
        {
            assertSchmoo("");
            assertSchmoo("abc\n123");
        }
    }

    /**
     * Compare an expected string with the given loaded template
     */
    protected void assertTmplEquals(String expected, String template)
    {
        info("Expected:  " + expected + " from '" + template + "'");

        StringWriter writer = new StringWriter();
        try
        {
            engine.mergeTemplate(template, "utf-8", context, writer);
        }
        catch (RuntimeException re)
        {
            info("RuntimeException!", re);
            throw re;
        }
        catch (Exception e)
        {
            info("Exception!", e);
            throw new RuntimeException(e);
        }

        info("Result:  " + writer.toString());
        assertEquals(expected, writer.toString());
    }

    /**
     * Ensure that a context value is as expected.
     */
    protected void assertContextValue(String key, Object expected)
    {
        info("Expected value of '"+key+"': "+expected);
        Object value = context.get(key);
        info("Result: "+value);
        assertEquals(expected, value);
    }

    /**
     * Ensure that a template renders as expected.
     */
    protected void assertEvalEquals(String expected, String template)
    {
        info("Expectation: "+expected);
        assertEquals(expected, evaluate(template));
    }

    /**
     * Ensure that the given string renders as itself when evaluated.
     */
    protected void assertSchmoo(String templateIsExpected)
    {
        assertEvalEquals(templateIsExpected, templateIsExpected);
    }

    /**
     * Ensure that an exception occurs when the string is evaluated.
     */
    protected Exception assertEvalException(String evil)
    {
        return assertEvalException(evil, null);
    }

    /**
     * Ensure that a specified type of exception occurs when evaluating the string.
     */
    protected Exception assertEvalException(String evil, Class exceptionType)
    {
        try
        {
            if (!DEBUG)
            {
                log.off();
            }
            if (exceptionType != null)
            {
                info("Expectation: "+exceptionType.getName());
            }
            else
            {
                info("Expectation: "+Exception.class.getName());
            }
            evaluate(evil);
            String msg = "Template '"+evil+"' should have thrown an exception.";
            info("Fail: "+msg);
            fail(msg);
        }
        catch (Exception e)
        {
            if (exceptionType != null && !exceptionType.isAssignableFrom(e.getClass()))
            {
                String msg = "Was expecting template '"+evil+"' to throw "+exceptionType+" not "+e;
                info("Fail: "+msg);
                fail(msg);
            }
            return e;
        }
        finally
        {
            if (!DEBUG)
            {
                log.on();
            }
        }
        return null;
    }

    /**
     * Ensure that the error message of the expected exception has the proper location info.
     */
    protected Exception assertEvalExceptionAt(String evil, String template,
                                              int line, int col)
    {
        String loc = template+"[line "+line+", column "+col+"]";
        info("Expectation: Exception at "+loc);
        Exception e = assertEvalException(evil);

        info("Result: "+e.getClass().getName()+" - "+e.getMessage());
        if (e.getMessage().indexOf(loc) < 1)
        {
            fail("Was expecting exception at "+loc+" instead of "+e.getMessage());
        }
        return e;
    }

    /**
     * Only ensure that the error message of the expected exception
     * has the proper line and column info.
     */
    protected Exception assertEvalExceptionAt(String evil, int line, int col)
    {
         return assertEvalExceptionAt(evil, "", line, col);
    }

    /**
     * Evaluate the specified String as a template and return the result as a String.
     */
    protected String evaluate(String template)
    {
        StringWriter writer = new StringWriter();
        try
        {
            info("Template: "+template);

            // use template as its own name, since our templates are short
            // unless it's not that short, then shorten it...
            String name = (template.length() <= 15) ? template : template.substring(0,15);
            engine.evaluate(context, writer, name, template);

            String result = writer.toString();
            info("Result: "+result);
            return result;
        }
        catch (RuntimeException re)
        {
            info("RuntimeException!", re);
            throw re;
        }
        catch (Exception e)
        {
            info("Exception!", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * Concatenates the file name parts together appropriately.
     *
     * @return The full path to the file.
     */
    protected String getFileName(final String dir, final String base, final String ext)
    {
        return getFileName(dir, base, ext, false);
    }

    protected String getFileName(final String dir, final String base, final String ext, final boolean mustExist)
    {
        StringBuffer buf = new StringBuffer();
        try
        {
            File baseFile = new File(base);
            if (dir != null)
            {
                if (!baseFile.isAbsolute())
                {
                    baseFile = new File(dir, base);
                }

                buf.append(baseFile.getCanonicalPath());
            }
            else
            {
                buf.append(baseFile.getPath());
            }

            if (org.apache.commons.lang3.StringUtils.isNotEmpty(ext))
            {
                buf.append('.').append(ext);
            }

            if (mustExist)
            {
                File testFile = new File(buf.toString());

                if (!testFile.exists())
                {
                    String msg = "getFileName() result " + testFile.getPath() + " does not exist!";
                    info(msg);
                    fail(msg);
                }

                if (!testFile.isFile())
                {
                    String msg = "getFileName() result " + testFile.getPath() + " is not a file!";
                    info(msg);
                    fail(msg);
                }
            }
        }
        catch (IOException e)
        {
            fail("IO Exception while running getFileName(" + dir + ", " + base + ", "+ ext + ", " + mustExist + "): " + e.getMessage());
        }

        return buf.toString();
    }

    /**
     * Assures that the results directory exists.  If the results directory
     * cannot be created, fails the test.
     */
    protected void assureResultsDirectoryExists(String resultsDirectory)
    {
        File dir = new File(resultsDirectory);
        if (!dir.exists())
        {
            info("Template results directory ("+resultsDirectory+") does not exist");
            if (dir.mkdirs())
            {
                info("Created template results directory");
                if (DEBUG)
                {
                    info("Created template results directory: "+resultsDirectory);
                }
            }
            else
            {
                String errMsg = "Unable to create '"+resultsDirectory+"'";
                info(errMsg);
                fail(errMsg);
            }
        }
    }


    /**
     * Normalizes lines to account for platform differences.  Macs use
     * a single \r, DOS derived operating systems use \r\n, and Unix
     * uses \n.  Replace each with a single \n.
     *
     * @return source with all line terminations changed to Unix style
     */
    protected String normalizeNewlines (String source)
    {
        return source.replaceAll("\r\n?", "\n");
    }

    /**
     * Returns whether the processed template matches the
     * content of the provided comparison file.
     *
     * @return Whether the output matches the contents
     *         of the comparison file.
     *
     * @exception Exception Test failure condition.
     */
    protected boolean isMatch (String resultsDir,
                               String compareDir,
                               String baseFileName,
                               String resultExt,
                               String compareExt) throws Exception
    {
        if (DEBUG)
        {
            info("Result: "+resultsDir+'/'+baseFileName+'.'+resultExt);
        }
        String result = getFileContents(resultsDir, baseFileName, resultExt);
        return isMatch(result,compareDir,baseFileName,compareExt);
    }


    protected String getFileContents(String dir, String baseFileName, String ext)
    {
        String fileName = getFileName(dir, baseFileName, ext, true);
        return StringUtils.fileContentsToString(fileName);
    }

    /**
     * Returns whether the processed template matches the
     * content of the provided comparison file.
     *
     * @return Whether the output matches the contents
     *         of the comparison file.
     *
     * @exception Exception Test failure condition.
     */
    protected boolean isMatch (String result,
                               String compareDir,
                               String baseFileName,
                               String compareExt) throws Exception
    {
        String compare = getFileContents(compareDir, baseFileName, compareExt);

        // normalize each wrt newline
        result = normalizeNewlines(result);
        compare = normalizeNewlines(compare);
        if (DEBUG)
        {
            info("Expection: "+compareDir+'/'+baseFileName+'.'+compareExt);
        }
        return result.equals(compare);
    }

    /**
     * Turns a base file name into a test case name.
     *
     * @param s The base file name.
     * @return  The test case name.
     */
    protected static final String getTestCaseName(String s)
    {
        StringBuffer name = new StringBuffer();
        name.append(Character.toTitleCase(s.charAt(0)));
        name.append(s.substring(1, s.length()).toLowerCase());
        return name.toString();
    }
}
