/*
 * Copyright (C) 2008 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.Constructor;

/**
 * DexFile tests (Dalvik-specific).
 */
public class Main {
    private static final String CLASS_PATH = "/data/art-test/071-dexfile-ex.jar";
    private static final String ODEX_DIR = "/data/art-test";
    //private static final String ODEX_DIR = ".";
    private static final String ODEX_ALT = "/tmp";
    private static final String LIB_DIR = "/nowhere/nothing/";

    /**
     * Prep the environment then run the test.
     */
    public static void main(String[] args) {
        Process p;
        try {
            /*
             * Create a sub-process to see if the ProcessManager wait
             * interferes with the dexopt invocation wait.
             *
             * /dev/random never hits EOF, so we're sure that we'll still
             * be waiting for the process to complete.  On the device it
             * stops pretty quickly (which means the child won't be
             * spinning).
             */
            ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
            p = pb.start();
        } catch (IOException ioe) {
            System.err.println("cmd failed: " + ioe.getMessage());
            p = null;
        }

        try {
            testDexClassLoader();
        } finally {
            // shouldn't be necessary, but it's good to be tidy
            if (p != null) {
                p.destroy();
            }

            // let the ProcessManager's daemon thread finish before we shut down
            // (avoids the occasional segmentation fault)
            try {
                Thread.sleep(500);
            } catch (Exception ex) {}
        }

        System.out.println("done");
    }

    /**
     * Create a class loader, explicitly specifying the source DEX and
     * the location for the optimized DEX.
     */
    private static void testDexClassLoader() {
        ClassLoader dexClassLoader = getDexClassLoader();

        Class anotherClass;
        try {
            anotherClass = dexClassLoader.loadClass("Another");
        } catch (ClassNotFoundException cnfe) {
            throw new RuntimeException("Another?", cnfe);
        }

        Object another;
        try {
            another = anotherClass.newInstance();
        } catch (IllegalAccessException ie) {
            throw new RuntimeException("new another", ie);
        } catch (InstantiationException ie) {
            throw new RuntimeException("new another", ie);
        }

        // not expected to work; just exercises the call
        dexClassLoader.getResource("nonexistent");
    }

    /*
     * Create an instance of DexClassLoader.  The test harness doesn't
     * have visibility into dalvik.system.*, so we do this through
     * reflection.
     */
    private static ClassLoader getDexClassLoader() {
        String odexDir;

        if (false) {
            String androidData = System.getenv("ANDROID_DATA");
            if (androidData == null) {
                androidData = "";
            }
            odexDir = androidData + "/" + ODEX_DIR;
        }

        File test = new File(ODEX_DIR);
        if (test.isDirectory()) {
            odexDir = ODEX_DIR;
        } else {
            odexDir = ODEX_ALT;
        }
        if (false) {
            System.out.println("Output dir is " + odexDir);
        }

        ClassLoader myLoader = Main.class.getClassLoader();
        Class dclClass;
        try {
            dclClass = myLoader.loadClass("dalvik.system.DexClassLoader");
        } catch (ClassNotFoundException cnfe) {
            throw new RuntimeException("dalvik.system.DexClassLoader not found", cnfe);
        }

        Constructor ctor;
        try {
            ctor = dclClass.getConstructor(String.class, String.class,
                String.class, ClassLoader.class);
        } catch (NoSuchMethodException nsme) {
            throw new RuntimeException("DCL ctor", nsme);
        }

        // create an instance, using the path we found
        Object dclObj;
        try {
            dclObj = ctor.newInstance(CLASS_PATH, odexDir, LIB_DIR, myLoader);
        } catch (Exception ex) {
            throw new RuntimeException("DCL newInstance", ex);
        }

        return (ClassLoader) dclObj;
    }
}
