/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed 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 dalvik.system;

import dalvik.system.CloseGuard.Reporter;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Provides support for detecting issues found by {@link CloseGuard} from within tests.
 *
 * <p>This is a best effort as it relies on both {@link CloseGuard} being enabled and being able to
 * force a GC and finalization, none of which are directly controllable by this.
 *
 * <p>This is loaded using reflection by the AbstractResourceLeakageDetectorTestCase class as that
 * class needs to run on the reference implementation which does not have this class. It implements
 * {@link Runnable} because that is simpler than trying to manage a specialized interface.
 *
 * @hide
 */
public class CloseGuardMonitor implements Runnable {
  /**
   * The {@link Reporter} instance used to receive warnings from {@link CloseGuard}.
   */
  private final Reporter closeGuardReporter;

  /**
   * The list of allocation sites that {@link CloseGuard} has reported as not being released.
   *
   * <p>Is thread safe as this will be called during finalization and so there are no guarantees
   * as to whether it will be called concurrently or not.
   */
  private final List<Throwable> closeGuardAllocationSites = new CopyOnWriteArrayList<>();

  /**
   * Default constructor required for reflection.
   */
  public CloseGuardMonitor() {
    System.logI("Creating CloseGuard monitor");

    // Save current reporter.
    closeGuardReporter = CloseGuard.getReporter();

    // Override the reporter with our own which collates the allocation sites.
    CloseGuard.setReporter(new Reporter() {
      @Override
      public void report(String message, Throwable allocationSite) {
        // Ignore message as it's always the same.
        closeGuardAllocationSites.add(allocationSite);
      }
    });
  }

  /**
   * Check to see whether any resources monitored by {@link CloseGuard} were not released before
   * they were garbage collected.
   */
  @Override
  public void run() {
    // Create a weak reference to an object so that we can detect when it is garbage collected.
    WeakReference<Object> reference = new WeakReference<>(new Object());

    try {
      // 'Force' a GC and finalize to cause CloseGuards to report warnings. Doesn't loop
      // forever as there are no guarantees that the following code does anything at all so
      // don't want a potential infinite loop.
      Runtime runtime = Runtime.getRuntime();
      for (int i = 0; i < 20; ++i) {
        runtime.gc();
        System.runFinalization();
        try {
          Thread.sleep(1);
        } catch (InterruptedException e) {
          throw new AssertionError(e);
        }

        // Check to see if the weak reference has been garbage collected.
        if (reference.get() == null) {
          System.logI("Sentry object has been freed so assuming CloseGuards have reported"
              + " any resource leakages");
          break;
        }
      }
    } finally {
      // Restore the reporter.
      CloseGuard.setReporter(closeGuardReporter);
    }

    if (!closeGuardAllocationSites.isEmpty()) {
      StringWriter writer = new StringWriter();
      PrintWriter printWriter = new PrintWriter(writer);
      int i = 0;
      for (Throwable allocationSite : closeGuardAllocationSites) {
        printWriter.print(++i);
        printWriter.print(") ");
        allocationSite.printStackTrace(printWriter);
        printWriter.println("    --------------------------------");
      }
      throw new AssertionError("Potential resource leakage detected:\n" + writer);
    }
  }
}
