/*
 * Copyright (C) 2009 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.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public class Main {
    private static final int TEST_LENGTH = 100;

    private static boolean makeArray(int i) {
        return i % 10 == 0;
    }

    private static void fillArray(Object global[], Object local[], int i) {
        // Very stupid linking.
        local[0] = global;
        for (int j = 1; j < local.length; j++) {
            local[j] = global[j];
        }
    }

    private static Object allocInDifferentLoader() throws Exception {
        final String DEX_FILE = System.getenv("DEX_LOCATION") + "/130-hprof-ex.jar";
        Class pathClassLoader = Class.forName("dalvik.system.PathClassLoader");
        if (pathClassLoader == null) {
            throw new AssertionError("Couldn't find path class loader class");
        }
        Constructor constructor =
            pathClassLoader.getDeclaredConstructor(String.class, ClassLoader.class);
        ClassLoader loader = (ClassLoader)constructor.newInstance(
                DEX_FILE, ClassLoader.getSystemClassLoader());
        Class allocator = loader.loadClass("Allocator");
        return allocator.getDeclaredMethod("allocObject", null).invoke(null);
    }

    private static void createDumpAndConv() throws RuntimeException {
        File dumpFile = null;
        File convFile = null;

        try {
            // Now dump the heap.
            dumpFile = createDump();

            // Run hprof-conv on it.
            convFile = getConvFile();

            File hprof_conv = getHprofConf();
            try {
                ProcessBuilder pb = new ProcessBuilder(
                        hprof_conv.getAbsoluteFile().toString(),
                        dumpFile.getAbsoluteFile().toString(),
                        convFile.getAbsoluteFile().toString());
                pb.redirectErrorStream(true);
                Process process = pb.start();
                int ret = process.waitFor();
                if (ret != 0) {
                    throw new RuntimeException("Exited abnormally with " + ret);
                }
            } catch (Exception exc) {
                throw new RuntimeException(exc);
            }
        } finally {
            // Delete the files.
            if (dumpFile != null) {
                dumpFile.delete();
            }
            if (convFile != null) {
                convFile.delete();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        // Create some data.
        Object data[] = new Object[TEST_LENGTH];
        for (int i = 0; i < data.length; i++) {
            if (makeArray(i)) {
                data[i] = new Object[TEST_LENGTH];
            } else {
                data[i] = String.valueOf(i);
            }
        }
        for (int i = 0; i < data.length; i++) {
            if (makeArray(i)) {
                Object data2[] = (Object[]) data[i];
                fillArray(data, data2, i);
            }
        }
        System.out.println("Generated data.");

        createDumpAndConv();
        Class klass = Class.forName("org.apache.harmony.dalvik.ddmc.DdmVmInternal");
        if (klass == null) {
            throw new AssertionError("Couldn't find path class loader class");
        }
        Method enableMethod = klass.getDeclaredMethod("enableRecentAllocations",
                Boolean.TYPE);
        if (enableMethod == null) {
            throw new AssertionError("Couldn't find path class loader class");
        }
        enableMethod.invoke(null, true);
        Object o = allocInDifferentLoader();
        // Run GC to cause class unloading.
        Runtime.getRuntime().gc();
        createDumpAndConv();
        // TODO: Somehow check contents of hprof file.
        enableMethod.invoke(null, false);
    }

    private static File getHprofConf() {
        // Use the java.library.path. It points to the lib directory.
        File libDir = new File(System.getProperty("java.library.path"));
        return new File(new File(libDir.getParentFile(), "bin"), "hprof-conv");
    }

    private static File createDump() {
        java.lang.reflect.Method dumpHprofDataMethod = getDumpHprofDataMethod();
        if (dumpHprofDataMethod != null) {
            File f = getDumpFile();
            try {
                dumpHprofDataMethod.invoke(null, f.getAbsoluteFile().toString());
                return f;
            } catch (Exception exc) {
                exc.printStackTrace(System.out);
            }
        } else {
            System.out.println("Could not find dump method!");
        }
        return null;
    }

    /**
     * Finds VMDebug.dumpHprofData() through reflection.  In the reference
     * implementation this will not be available.
     *
     * @return the reflection object, or null if the method can't be found
     */
    private static Method getDumpHprofDataMethod() {
        ClassLoader myLoader = Main.class.getClassLoader();
        Class vmdClass;
        try {
            vmdClass = myLoader.loadClass("dalvik.system.VMDebug");
        } catch (ClassNotFoundException cnfe) {
            return null;
        }

        Method meth;
        try {
            meth = vmdClass.getMethod("dumpHprofData",
                    new Class[] { String.class });
        } catch (NoSuchMethodException nsme) {
            System.err.println("Found VMDebug but not dumpHprofData method");
            return null;
        }

        return meth;
    }

    private static File getDumpFile() {
        try {
            return File.createTempFile("test-130-hprof", "dump");
        } catch (Exception exc) {
            return null;
        }
    }

    private static File getConvFile() {
        try {
            return File.createTempFile("test-130-hprof", "conv");
        } catch (Exception exc) {
            return null;
        }
    }
}
