/*
 * 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.commons.jelly.core;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import junit.framework.TestCase;

import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.jelly.parser.XMLParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Automates the basic process of testing a tag library for a memory leak.
 * <p>
 * To use it, extend it. Use the {@link runScriptManyTimes(String, int)}
 * method in your unit tests.
 * 
 * @author Hans Gilde
 *  
 */
public abstract class BaseMemoryLeakTest extends TestCase {
    private final static Log log = LogFactory.getLog(BaseMemoryLeakTest.class);

    /**
     * The JUnit constructor
     * 
     * @param name
     */
    public BaseMemoryLeakTest(String name) {
        super(name);
    }

    /** Runs a script count times and reports the number of bytes "leaked".
     * Note that "leaked" means "not collected by the GC"
     * and can easily be different between JVM's. This is because all 
     * freed references may not be available for GC in the short time
     * between their freeing and the completion of this test.
     * <p/>
     * However, running a 
     * script 10,000 or 100,000 times should be a pretty good test
     * for a memory leak. If there's not too much memory "leaked",
     * you're probably OK.
     * @param scriptName The path to the script, from the classloader of the current class.
     * @param count The number of times to run the script.
     * @return The number of bytes "leaked"
     * @throws IOException
     * @throws SAXException
     * @throws JellyException
     */
    public long runScriptManyTimes(String scriptName, int count)
            throws IOException, SAXException, JellyException {
        Runtime rt = Runtime.getRuntime();
        JellyContext jc = new JellyContext();
        jc.setClassLoader(getClass().getClassLoader());

        XMLOutput output = XMLOutput.createDummyXMLOutput();
        
        URL url = this.getClass().getResource(scriptName);

        String exturl = url.toExternalForm();
        int lastSlash = exturl.lastIndexOf("/");
        String extBase = exturl.substring(0,lastSlash+1);
        URL baseurl = new URL(extBase);
        jc.setCurrentURL(baseurl);
        
        InputStream is = url.openStream();
        byte[] bytes = new byte[is.available()];
        is.read(bytes);

        InputStream scriptIStream = new ByteArrayInputStream(bytes);
        InputSource scriptISource = new InputSource(scriptIStream);

        is.close();
        is = null;
        bytes = null;

        rt.runFinalization();
        rt.gc();

        long start = rt.totalMemory() - rt.freeMemory();
        log.info("Starting memory test with used memory of " + start);

        XMLParser parser;
        Script script;

        int outputEveryXIterations = outputEveryXIterations();

        for (int i = 0; i < count; i++) {
            scriptIStream.reset();
            parser = new XMLParser();

            script = parser.parse(scriptISource);
            script.run(jc, output);
            // PL: I don't see why but removing the clear here 
            //     does make the test fail!
            //     As if the WeakHashMap wasn't weak enough...
            
            //Hans: The structure of the relationship
            //  between TagScript and Tag prevents WeakHashMap
            //  from working in this case, which is why I removed it.
            jc.clear();

            if (outputEveryXIterations != 0 && i % outputEveryXIterations == 0) {
                parser = null;
                script = null;
                
                rt.runFinalization();
                rt.gc();
                long middle = rt.totalMemory() - rt.freeMemory();
                log.info("Memory test after " + i + " runs: "
                        + (middle - start));
            }
        }
        
        rt.gc();

        jc = null;
        output = null;
        parser = null;
        script = null;

        scriptIStream = null;
        scriptISource = null;

        rt.runFinalization();
        rt.gc();
        
        long nullsDone = rt.totalMemory() - rt.freeMemory();
        log.info("Memory test completed, memory \"leaked\": " + (nullsDone - start));
        
        return nullsDone - start;
    }

    protected int outputEveryXIterations() {
        return 1000;
    }

}
