/*
 * 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 = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar";
    private static final String ODEX_DIR = System.getenv("DEX_LOCATION");
    //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;
    }
}
