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

import static org.junit.jupiter.api.Assertions.assertNull;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple utility class that can verify that objects have been successfully garbage collected.
 *
 * Usage is something like
 *
 * 	private final MemoryLeakVerifier verifier = new MemoryLeakVerifier();

	{@literal}After
	void tearDown() {
		verifier.assertGarbageCollected();
	}

	{@literal}Test
	void someTest() {
		...
		verifier.addObject(object);
	}

 *
 * This will verify at the end of the test if the object is actually removed by the
 * garbage collector or if it lingers in memory for some reason.
 *
 * Idea taken from http://stackoverflow.com/a/7410460/411846
 */
public class MemoryLeakVerifier {
	private static final int MAX_GC_ITERATIONS = 50;
	private static final int GC_SLEEP_TIME     = 100;

	private final List<WeakReference<Object>> references = new ArrayList<>();

	public MemoryLeakVerifier() {
	}

	public void addObject(Object object) {
		references.add(new WeakReference<>(object));
	}

	/**
	 * Attempts to perform a full garbage collection so that all weak references will be removed. Usually only
	 * a single GC is required, but there have been situations where some unused memory is not cleared up on the
	 * first pass. This method performs a full garbage collection and then validates that the weak reference
	 * now has been cleared. If it hasn't then the thread will sleep for 100 milliseconds and then retry up to
	 * 50 more times. If after this the object still has not been collected then the assertion will fail.
	 *
	 * Based upon the method described in: http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
	 */
	public void assertGarbageCollected() {
		assertGarbageCollected(MAX_GC_ITERATIONS);
	}

	/**
	 * Used only for testing the class itself where we would like to fail faster than 5 seconds
	 * @param maxIterations The number of times a GC will be invoked until a possible memory leak is reported
	 */
	void assertGarbageCollected(int maxIterations) {
		try {
			for(WeakReference<Object> ref : references) {
				assertGarbageCollected(ref, maxIterations);
			}
		} catch (InterruptedException e) {
			// just ensure that we quickly return when the thread is interrupted
		}
	}

	private static void assertGarbageCollected(WeakReference<Object> ref, int maxIterations) throws InterruptedException {
	    Runtime runtime = Runtime.getRuntime();
	    for (int i = 0; i < maxIterations; i++) {
	        runtime.runFinalization();
	        runtime.gc();
	        if (ref.get() == null)
	            break;

	        // Pause for a while and then go back around the loop to try again...
			//EventQueue.invokeAndWait(Procedure.NoOp); // Wait for the AWT event queue to have completed processing
			Thread.sleep(GC_SLEEP_TIME);
	    }

	    assertNull(ref.get(), "Object should not exist after " + MAX_GC_ITERATIONS + " collections, but still had: " + ref.get());
	}
}
