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

package dalvik.system;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.File;
import java.io.FilenameFilter;

/**
 * Induces optimization/verification of a set of DEX files.
 *
 * @deprecated this is an internal Dalvik class that is not appropriate for
 *      general use. It will be removed from the public API in a future release.
 */
public class TouchDex {

    /**
     * Forks a process, makes sure the DEX files are prepared, and returns
     * when everything is finished.
     * <p>
     * The filenames must be the same as will be used when the files are
     * actually opened, because the dalvik-cache filename is based upon
     * this filename.  (The absolute path to the JAR/ZIP/APK should work.)
     *
     * @param dexFiles a colon-separated list of DEX files.
     * @return zero on success
     * 
     * @cts What about error cases?
     */
    public static int start(String dexFiles) {
        return trampoline(dexFiles, System.getProperty("java.boot.class.path"));
    }

    /**
     * This calls fork() and then, in the child, calls cont(dexFiles).
     *
     * @param dexFiles Colon-separated list of DEX files.
     * @return zero on success
     */
    native private static int trampoline(String dexFiles, String bcp);

    /**
     * The entry point for the child process. args[0] can be a colon-separated
     * path list, or "-" to read from stdin.
     * <p>
     * Alternatively, if we're invoked directly from the command line we
     * just start here (skipping the fork/exec stuff).
     *
     * @param args command line args
     */
    public static void main(String[] args) {

        if ("-".equals(args[0])) {
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(System.in), 256);

            String line;
            try {
                while ((line = in.readLine()) != null) {
                    prepFiles(line);
                }
            } catch (IOException ex) {
                throw new RuntimeException ("Error processing stdin");
            }
        } else {
            prepFiles(args[0]);
        }

        System.out.println(" Prep complete");
    }


    private static String expandDirectories(String dexPath) {
        String[] parts = dexPath.split(":");
        StringBuilder outPath = new StringBuilder(dexPath.length());

        // A filename filter accepting *.jar and *.apk
        FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".jar") || name.endsWith(".apk");
            }
        };

        for (String part: parts) {
            File f = new File(part);

            if (f.isFile()) {
                outPath.append(part);
                outPath.append(':');
            } else if (f.isDirectory()) {
                String[] filenames = f.list(filter);

                if (filenames == null) {
                    System.err.println("I/O error with directory: " + part);
                    continue;
                }

                for (String filename: filenames) {
                    outPath.append(part);
                    outPath.append(File.separatorChar);
                    outPath.append(filename);
                    outPath.append(':');
                }
            } else {
                System.err.println("File not found: " + part);
            }
        }


        return outPath.toString();
    }

    private static void prepFiles(String dexPath) {

        System.out.println(" Prepping: " + dexPath);

        TouchDexLoader loader
                = new TouchDexLoader(expandDirectories(dexPath), null);

        try {
            /* By looking for a nonexistent class, we'll trick TouchDexLoader
             * into trying to load something from every file on dexPath,
             * optimizing all of them as a side-effect.
             *
             * The optimization happens implicitly in the VM the first time
             * someone tries to load a class from an unoptimized dex file.
             */
            loader.loadClass("com.google.NonexistentClassNeverFound");
            throw new RuntimeException("nonexistent class loaded?!");
        } catch (ClassNotFoundException cnfe) {
            //System.out.println("got expected dnfe");
        }
    }
}

