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

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Map;

public class Main {
    private static final String TEMP_FILE_NAME_PREFIX = "test";
    private static final String TEMP_FILE_NAME_SUFFIX = ".trace";

    public static void main(String[] args) throws Exception {
        String name = System.getProperty("java.vm.name");
        if (!"Dalvik".equals(name)) {
            System.out.println("This test is not supported on " + name);
            return;
        }
        testMethodTracing();
        testCountInstances();
        testRuntimeStat();
        testRuntimeStats();
    }

    private static File createTempFile() throws Exception {
        try {
            return  File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
        } catch (IOException e) {
            System.setProperty("java.io.tmpdir", "/data/local/tmp");
            try {
                return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
            } catch (IOException e2) {
                System.setProperty("java.io.tmpdir", "/sdcard");
                return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
            }
        }
    }

    private static void testMethodTracing() throws Exception {
        File tempFile = null;
        try {
            tempFile = createTempFile();
            testMethodTracingToFile(tempFile);
        } finally {
            if (tempFile != null) {
                tempFile.delete();
            }
        }
    }

    private static void testMethodTracingToFile(File tempFile) throws Exception {
        String tempFileName = tempFile.getPath();

        if (VMDebug.getMethodTracingMode() != 0) {
            VMDebug.stopMethodTracing();
        }

        System.out.println("Confirm enable/disable");
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        VMDebug.stopMethodTracing();
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        if (tempFile.length() == 0) {
            System.out.println("ERROR: tracing output file is empty");
        }

        System.out.println("Confirm sampling");
        VMDebug.startMethodTracing(tempFileName, 0, 0, true, 1000);
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        VMDebug.stopMethodTracing();
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        if (tempFile.length() == 0) {
            System.out.println("ERROR: sample tracing output file is empty");
        }

        System.out.println("Test starting when already started");
        VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        VMDebug.startMethodTracing(tempFileName, 0, 0, false, 0);
        System.out.println("status=" + VMDebug.getMethodTracingMode());

        System.out.println("Test stopping when already stopped");
        VMDebug.stopMethodTracing();
        System.out.println("status=" + VMDebug.getMethodTracingMode());
        VMDebug.stopMethodTracing();
        System.out.println("status=" + VMDebug.getMethodTracingMode());

        System.out.println("Test tracing with empty filename");
        try {
            VMDebug.startMethodTracing("", 0, 0, false, 0);
            System.out.println("Should have thrown an exception");
        } catch (Exception e) {
            System.out.println("Got expected exception");
        }

        System.out.println("Test tracing with bogus (< 1024 && != 0) filesize");
        try {
            VMDebug.startMethodTracing(tempFileName, 1000, 0, false, 0);
            System.out.println("Should have thrown an exception");
        } catch (Exception e) {
            System.out.println("Got expected exception");
        }

        System.out.println("Test sampling with bogus (<= 0) interval");
        try {
            VMDebug.startMethodTracing(tempFileName, 0, 0, true, 0);
            System.out.println("Should have thrown an exception");
        } catch (Exception e) {
            System.out.println("Got expected exception");
        }

        tempFile.delete();
    }

    private static void checkNumber(String s) throws Exception {
        if (s == null) {
            System.out.println("Got null string");
            return;
        }
        long n = Long.valueOf(s);
        if (n < 0) {
            System.out.println("Got negative number " + n);
        }
    }

    private static void checkHistogram(String s) throws Exception {
        if (s == null || s.length() == 0) {
            System.out.println("Got null or empty string");
            return;
        }
        String[] buckets = s.split(",");
        long last_key = 0;
        for (int i = 0; i < buckets.length; ++i) {
            String bucket = buckets[i];
            if (bucket.length() == 0) {
                System.out.println("Got empty bucket");
                continue;
            }
            String[] kv = bucket.split(":");
            if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == 0) {
                System.out.println("Got bad bucket " + bucket);
                continue;
            }
            long key = Long.valueOf(kv[0]);
            long value = Long.valueOf(kv[1]);
            if (key < 0 || value < 0) {
                System.out.println("Got negative key or value " + bucket);
                continue;
            }
            if (key < last_key) {
                System.out.println("Got decreasing key " + bucket);
                continue;
            }
            last_key = key;
        }
    }

    private static void testRuntimeStat() throws Exception {
        // Invoke at least one GC and wait for 20 seconds or so so we get at
        // least one bucket in the histograms.
        for (int i = 0; i < 20; ++i) {
          Runtime.getRuntime().gc();
          Thread.sleep(1000L);
        }
        String gc_count = VMDebug.getRuntimeStat("art.gc.gc-count");
        String gc_time = VMDebug.getRuntimeStat("art.gc.gc-time");
        String bytes_allocated = VMDebug.getRuntimeStat("art.gc.bytes-allocated");
        String bytes_freed = VMDebug.getRuntimeStat("art.gc.bytes-freed");
        String blocking_gc_count = VMDebug.getRuntimeStat("art.gc.blocking-gc-count");
        String blocking_gc_time = VMDebug.getRuntimeStat("art.gc.blocking-gc-time");
        String gc_count_rate_histogram = VMDebug.getRuntimeStat("art.gc.gc-count-rate-histogram");
        String blocking_gc_count_rate_histogram =
            VMDebug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram");
        checkNumber(gc_count);
        checkNumber(gc_time);
        checkNumber(bytes_allocated);
        checkNumber(bytes_freed);
        checkNumber(blocking_gc_count);
        checkNumber(blocking_gc_time);
        checkHistogram(gc_count_rate_histogram);
        checkHistogram(blocking_gc_count_rate_histogram);
    }

    private static void testRuntimeStats() throws Exception {
        // Invoke at least one GC and wait for 20 seconds or so so we get at
        // least one bucket in the histograms.
        for (int i = 0; i < 20; ++i) {
          Runtime.getRuntime().gc();
          Thread.sleep(1000L);
        }
        Map<String, String> map = VMDebug.getRuntimeStats();
        String gc_count = map.get("art.gc.gc-count");
        String gc_time = map.get("art.gc.gc-time");
        String bytes_allocated = map.get("art.gc.bytes-allocated");
        String bytes_freed = map.get("art.gc.bytes-freed");
        String blocking_gc_count = map.get("art.gc.blocking-gc-count");
        String blocking_gc_time = map.get("art.gc.blocking-gc-time");
        String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram");
        String blocking_gc_count_rate_histogram =
            map.get("art.gc.blocking-gc-count-rate-histogram");
        checkNumber(gc_count);
        checkNumber(gc_time);
        checkNumber(bytes_allocated);
        checkNumber(bytes_freed);
        checkNumber(blocking_gc_count);
        checkNumber(blocking_gc_time);
        checkHistogram(gc_count_rate_histogram);
        checkHistogram(blocking_gc_count_rate_histogram);
    }

    static class ClassA { }
    static class ClassB { }
    static class ClassC extends ClassA { }

    private static void testCountInstances() throws Exception {
        ArrayList<Object> l = new ArrayList<Object>();
        l.add(new ClassA());
        l.add(new ClassB());
        l.add(new ClassA());
        l.add(new ClassC());
        Runtime.getRuntime().gc();
        System.out.println("Instances of ClassA " +
                VMDebug.countInstancesofClass(ClassA.class, false));
        System.out.println("Instances of ClassB " +
                VMDebug.countInstancesofClass(ClassB.class, false));
        System.out.println("Instances of null " + VMDebug.countInstancesofClass(null, false));
        System.out.println("Instances of ClassA assignable " +
                VMDebug.countInstancesofClass(ClassA.class, true));
        Class[] classes = new Class[]{ClassA.class, ClassB.class, null};
        long[] counts = VMDebug.countInstancesofClasses(classes, false);
        System.out.println("Array counts " + Arrays.toString(counts));
        counts = VMDebug.countInstancesofClasses(classes, true);
        System.out.println("Array counts assignable " + Arrays.toString(counts));
    }

    private static class VMDebug {
        private static final Method startMethodTracingMethod;
        private static final Method stopMethodTracingMethod;
        private static final Method getMethodTracingModeMethod;
        private static final Method getRuntimeStatMethod;
        private static final Method getRuntimeStatsMethod;
        private static final Method countInstancesOfClassMethod;
        private static final Method countInstancesOfClassesMethod;
        static {
            try {
                Class c = Class.forName("dalvik.system.VMDebug");
                startMethodTracingMethod = c.getDeclaredMethod("startMethodTracing", String.class,
                        Integer.TYPE, Integer.TYPE, Boolean.TYPE, Integer.TYPE);
                stopMethodTracingMethod = c.getDeclaredMethod("stopMethodTracing");
                getMethodTracingModeMethod = c.getDeclaredMethod("getMethodTracingMode");
                getRuntimeStatMethod = c.getDeclaredMethod("getRuntimeStat", String.class);
                getRuntimeStatsMethod = c.getDeclaredMethod("getRuntimeStats");
                countInstancesOfClassMethod = c.getDeclaredMethod("countInstancesOfClass",
                        Class.class, Boolean.TYPE);
                countInstancesOfClassesMethod = c.getDeclaredMethod("countInstancesOfClasses",
                        Class[].class, Boolean.TYPE);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        public static void startMethodTracing(String filename, int bufferSize, int flags,
                boolean samplingEnabled, int intervalUs) throws Exception {
            startMethodTracingMethod.invoke(null, filename, bufferSize, flags, samplingEnabled,
                    intervalUs);
        }
        public static void stopMethodTracing() throws Exception {
            stopMethodTracingMethod.invoke(null);
        }
        public static int getMethodTracingMode() throws Exception {
            return (int) getMethodTracingModeMethod.invoke(null);
        }
        public static String getRuntimeStat(String statName) throws Exception {
            return (String) getRuntimeStatMethod.invoke(null, statName);
        }
        public static Map<String, String> getRuntimeStats() throws Exception {
            return (Map<String, String>) getRuntimeStatsMethod.invoke(null);
        }
        public static long countInstancesofClass(Class c, boolean assignable) throws Exception {
            return (long) countInstancesOfClassMethod.invoke(null, new Object[]{c, assignable});
        }
        public static long[] countInstancesofClasses(Class[] classes, boolean assignable)
                throws Exception {
            return (long[]) countInstancesOfClassesMethod.invoke(
                    null, new Object[]{classes, assignable});
        }
    }
}
