/*
 * Copyright (C) 2016 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.
 */

import java.util.ArrayList;

public class Main {
  public static void main(String[] args) throws Exception {
    System.loadLibrary(args[1]);

    // Use a list to ensure objects must be allocated.
    ArrayList<Object> l = new ArrayList<>(100);

    prefetchClassNames();

    doTest(l);
  }

  // Pre-resolve class names so the strings don't have to be allocated as a side effect of
  // callback printing.
  private static void prefetchClassNames() {
      Object.class.getName();
      Integer.class.getName();
      Float.class.getName();
      Short.class.getName();
      Byte.class.getName();
      Double.class.getName();
  }

  public static void doTest(ArrayList<Object> l) throws Exception {
    // Disable the global registration from OnLoad, to get into a known state.
    enableAllocationTracking(null, false);

    // Enable actual logging callback.
    setupObjectAllocCallback(true);

    enableAllocationTracking(null, true);

    l.add(new Object());
    l.add(new Integer(1));

    enableAllocationTracking(null, false);

    l.add(new Float(1.0f));

    enableAllocationTracking(Thread.currentThread(), true);

    l.add(new Short((short)0));

    enableAllocationTracking(Thread.currentThread(), false);

    l.add(new Byte((byte)0));

    System.out.println("Tracking on same thread");

    testThread(l, true, true);

    l.add(new Byte((byte)0));

    System.out.println("Tracking on same thread, not disabling tracking");

    testThread(l, true, false);

    System.out.println("Tracking on different thread");

    testThread(l, false, true);

    l.add(new Byte((byte)0));

    // Disable actual logging callback and re-enable tracking, so we can keep the event enabled and
    // check that shutdown works correctly.
    setupObjectAllocCallback(false);
    enableAllocationTracking(null, true);
  }

  private static void testThread(final ArrayList<Object> l, final boolean sameThread,
      final boolean disableTracking) throws Exception {
    final SimpleBarrier startBarrier = new SimpleBarrier(1);
    final SimpleBarrier trackBarrier = new SimpleBarrier(1);
    final SimpleBarrier disableBarrier = new SimpleBarrier(1);

    final Thread thisThread = Thread.currentThread();

    Thread t = new Thread() {
      public void run() {
        try {
          startBarrier.dec();
          trackBarrier.waitFor();
        } catch (Exception e) {
          e.printStackTrace(System.out);
          System.exit(1);
        }

        l.add(new Double(0.0));

        if (disableTracking) {
          enableAllocationTracking(sameThread ? this : thisThread, false);
        }
      }
    };

    t.start();
    startBarrier.waitFor();
    enableAllocationTracking(sameThread ? t : Thread.currentThread(), true);
    trackBarrier.dec();

    t.join();
  }

  private static class SimpleBarrier {
    int count;

    public SimpleBarrier(int i) {
      count = i;
    }

    public synchronized void dec() throws Exception {
      count--;
      notifyAll();
    }

    public synchronized void waitFor() throws Exception  {
      while (count != 0) {
        wait();
      }
    }
  }

  private static native void setupObjectAllocCallback(boolean enable);
  private static native void enableAllocationTracking(Thread thread, boolean enable);
}
