/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.sdk;

import com.android.SdkConstants;
import com.google.common.io.Closeables;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.management.InvalidAttributeValueException;

/**
 * Custom class loader able to load a class from the SDK jar file.
 */
public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader {

    /**
     * Wrapper around a {@link Class} to provide the methods of
     * {@link IAndroidClassLoader.IClassDescriptor}.
     */
    public final static class ClassWrapper implements IClassDescriptor {
        private Class<?> mClass;

        public ClassWrapper(Class<?> clazz) {
            mClass = clazz;
        }

        @Override
        public String getFullClassName() {
            return mClass.getCanonicalName();
        }

        @Override
        public IClassDescriptor[] getDeclaredClasses() {
            Class<?>[] classes = mClass.getDeclaredClasses();
            IClassDescriptor[] iclasses = new IClassDescriptor[classes.length];
            for (int i = 0 ; i < classes.length ; i++) {
                iclasses[i] = new ClassWrapper(classes[i]);
            }

            return iclasses;
        }

        @Override
        public IClassDescriptor getEnclosingClass() {
            return new ClassWrapper(mClass.getEnclosingClass());
        }

        @Override
        public String getSimpleName() {
            return mClass.getSimpleName();
        }

        @Override
        public IClassDescriptor getSuperclass() {
            return new ClassWrapper(mClass.getSuperclass());
        }

        @Override
        public boolean equals(Object clazz) {
            if (clazz instanceof ClassWrapper) {
                return mClass.equals(((ClassWrapper)clazz).mClass);
            }
            return super.equals(clazz);
        }

        @Override
        public int hashCode() {
            return mClass.hashCode();
        }


        @Override
        public boolean isInstantiable() {
            int modifiers = mClass.getModifiers();
            return Modifier.isAbstract(modifiers) == false && Modifier.isPublic(modifiers) == true;
        }

        public Class<?> wrappedClass() {
            return mClass;
        }

    }

    private String mOsFrameworkLocation;

    /** A cache for binary data extracted from the zip */
    private final HashMap<String, byte[]> mEntryCache = new HashMap<String, byte[]>();
    /** A cache for already defined Classes */
    private final HashMap<String, Class<?> > mClassCache = new HashMap<String, Class<?> >();

    /**
     * Creates the class loader by providing the os path to the framework jar archive
     *
     * @param osFrameworkLocation OS Path of the framework JAR file
     */
    public AndroidJarLoader(String osFrameworkLocation) {
        super();
        mOsFrameworkLocation = osFrameworkLocation;
    }

    @Override
    public String getSource() {
        return mOsFrameworkLocation;
    }

    /**
     * Pre-loads all class binary data that belong to the given package by reading the archive
     * once and caching them internally.
     * <p/>
     * This does not actually preload "classes", it just reads the unzipped bytes for a given
     * class. To obtain a class, one must call {@link #findClass(String)} later.
     * <p/>
     * All classes which package name starts with "packageFilter" will be included and can be
     * found later.
     * <p/>
     * May throw some exceptions if the framework JAR cannot be read.
     *
     * @param packageFilter The package that contains all the class data to preload, using a fully
     *                    qualified binary name (.e.g "com.my.package."). The matching algorithm
     *                    is simple "startsWith". Use an empty string to include everything.
     * @param taskLabel An optional task name for the sub monitor. Can be null.
     * @param monitor A progress monitor. Can be null. Caller is responsible for calling done.
     * @throws IOException
     * @throws InvalidAttributeValueException
     * @throws ClassFormatError
     */
    public void preLoadClasses(String packageFilter, String taskLabel, IProgressMonitor monitor)
        throws IOException, InvalidAttributeValueException, ClassFormatError {
        // Transform the package name into a zip entry path
        String pathFilter = packageFilter.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$

        SubMonitor progress = SubMonitor.convert(monitor, taskLabel == null ? "" : taskLabel, 100);

        // create streams to read the intermediary archive
        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry entry;
        while ((entry = zis.getNextEntry()) != null) {
            // get the name of the entry.
            String entryPath = entry.getName();

            if (!entryPath.endsWith(SdkConstants.DOT_CLASS)) {
                // only accept class files
                continue;
            }

            // check if it is part of the package to preload
            if (pathFilter.length() > 0 && !entryPath.startsWith(pathFilter)) {
                continue;
            }
            String className = entryPathToClassName(entryPath);

            if (!mEntryCache.containsKey(className)) {
                long entrySize = entry.getSize();
                if (entrySize > Integer.MAX_VALUE) {
                    throw new InvalidAttributeValueException();
                }
                byte[] data = readZipData(zis, (int)entrySize);
                mEntryCache.put(className, data);
            }

            // advance 5% of whatever is allocated on the progress bar
            progress.setWorkRemaining(100);
            progress.worked(5);
            progress.subTask(String.format("Preload %1$s", className));
        }
    }

    /**
     * Finds and loads all classes that derive from a given set of super classes.
     * <p/>
     * As a side-effect this will load and cache most, if not all, classes in the input JAR file.
     *
     * @param packageFilter Base name of package of classes to find.
     *                      Use an empty string to find everyting.
     * @param superClasses The super classes of all the classes to find.
     * @return An hash map which keys are the super classes looked for and which values are
     *         ArrayList of the classes found. The array lists are always created for all the
     *         valid keys, they are simply empty if no deriving class is found for a given
     *         super class.
     * @throws IOException
     * @throws InvalidAttributeValueException
     * @throws ClassFormatError
     */
    @SuppressWarnings("resource") // Eclipse doesn't understand Closeables.closeQuietly
    @Override
    public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom(
            String packageFilter,
            String[] superClasses)
            throws IOException, InvalidAttributeValueException, ClassFormatError {

        packageFilter = packageFilter.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$

        HashMap<String, ArrayList<IClassDescriptor>> mClassesFound =
                new HashMap<String, ArrayList<IClassDescriptor>>();

        for (String className : superClasses) {
            mClassesFound.put(className, new ArrayList<IClassDescriptor>());
        }

        // create streams to read the intermediary archive
        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
        ZipInputStream zis = new ZipInputStream(fis);
        try {
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                // get the name of the entry and convert to a class binary name
                String entryPath = entry.getName();
                if (!entryPath.endsWith(SdkConstants.DOT_CLASS)) {
                    // only accept class files
                    continue;
                }
                if (packageFilter.length() > 0 && !entryPath.startsWith(packageFilter)) {
                    // only accept stuff from the requested root package.
                    continue;
                }
                String className = entryPathToClassName(entryPath);

                Class<?> loaded_class = mClassCache.get(className);
                if (loaded_class == null) {
                    byte[] data = mEntryCache.get(className);
                    if (data == null) {
                        // Get the class and cache it
                        long entrySize = entry.getSize();
                        if (entrySize > Integer.MAX_VALUE) {
                            throw new InvalidAttributeValueException();
                        }
                        data = readZipData(zis, (int)entrySize);
                    }
                    try {
                        loaded_class = defineAndCacheClass(className, data);
                    } catch (NoClassDefFoundError error) {
                        if (error.getMessage().startsWith("java/")) {
                            // Can't define these; we just need to stop
                            // iteration here
                            continue;
                        }
                        throw error;
                    }
                }

                for (Class<?> superClass = loaded_class.getSuperclass();
                        superClass != null;
                        superClass = superClass.getSuperclass()) {
                    String superName = superClass.getCanonicalName();
                    if (mClassesFound.containsKey(superName)) {
                        mClassesFound.get(superName).add(new ClassWrapper(loaded_class));
                        break;
                    }
                }
            }
        } finally {
            Closeables.closeQuietly(zis);
        }

        return mClassesFound;
    }

    /** Helper method that converts a Zip entry path into a corresponding
     *  Java full qualified binary class name.
     *  <p/>
     *  F.ex, this converts "com/my/package/Foo.class" into "com.my.package.Foo".
     */
    private String entryPathToClassName(String entryPath) {
        return entryPath.replaceFirst("\\.class$", "").replaceAll("[/\\\\]", "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }

    /**
     * Finds the class with the specified binary name.
     *
     * {@inheritDoc}
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            // try to find the class in the cache
            Class<?> cached_class = mClassCache.get(name);
            if (cached_class == ClassNotFoundException.class) {
                // we already know we can't find this class, don't try again
                throw new ClassNotFoundException(name);
            } else if (cached_class != null) {
                return cached_class;
            }

            // if not found, look it up and cache it
            byte[] data = loadClassData(name);
            if (data != null) {
                return defineAndCacheClass(name, data);
            } else {
                // if the class can't be found, record a CNFE class in the map so
                // that we don't try to reload it next time
                mClassCache.put(name, ClassNotFoundException.class);
                throw new ClassNotFoundException(name);
            }
        } catch (ClassNotFoundException e) {
            throw e;
        } catch (Exception e) {
            throw new ClassNotFoundException(e.getMessage());
        }
    }

    /**
     * Defines a class based on its binary data and caches the resulting class object.
     *
     * @param name The binary name of the class (i.e. package.class1$class2)
     * @param data The binary data from the loader.
     * @return The class defined
     * @throws ClassFormatError if defineClass failed.
     */
    private Class<?> defineAndCacheClass(String name, byte[] data) throws ClassFormatError {
        Class<?> cached_class;
        cached_class = defineClass(null, data, 0, data.length);

        if (cached_class != null) {
            // Add new class to the cache class and remove it from the zip entry data cache
            mClassCache.put(name, cached_class);
            mEntryCache.remove(name);
        }
        return cached_class;
    }

    /**
     * Loads a class data from its binary name.
     * <p/>
     * This uses the class binary data that has been preloaded earlier by the preLoadClasses()
     * method if possible.
     *
     * @param className the binary name
     * @return an array of bytes representing the class data or null if not found
     * @throws InvalidAttributeValueException
     * @throws IOException
     */
    private synchronized byte[] loadClassData(String className)
            throws InvalidAttributeValueException, IOException {

        byte[] data = mEntryCache.get(className);
        if (data != null) {
            return data;
        }

        // The name is a binary name. Something like "android.R", or "android.R$id".
        // Make a path out of it.
        String entryName = className.replaceAll("\\.", "/") + SdkConstants.DOT_CLASS; //$NON-NLS-1$ //$NON-NLS-2$

       // create streams to read the intermediary archive
        FileInputStream fis = new FileInputStream(mOsFrameworkLocation);
        ZipInputStream zis = new ZipInputStream(fis);
        try {
            // loop on the entries of the intermediary package and put them in the final package.
            ZipEntry entry;

            while ((entry = zis.getNextEntry()) != null) {
                // get the name of the entry.
                String currEntryName = entry.getName();

                if (currEntryName.equals(entryName)) {
                    long entrySize = entry.getSize();
                    if (entrySize > Integer.MAX_VALUE) {
                        throw new InvalidAttributeValueException();
                    }

                    data = readZipData(zis, (int)entrySize);
                    return data;
                }
            }

            return null;
        } finally {
            zis.close();
        }
    }

    /**
     * Reads data for the <em>current</em> entry from the zip input stream.
     *
     * @param zis The Zip input stream
     * @param entrySize The entry size. -1 if unknown.
     * @return The new data for the <em>current</em> entry.
     * @throws IOException If ZipInputStream.read() fails.
     */
    private byte[] readZipData(ZipInputStream zis, int entrySize) throws IOException {
        int block_size = 1024;
        int data_size = entrySize < 1 ? block_size : entrySize;
        int offset = 0;
        byte[] data = new byte[data_size];

        while(zis.available() != 0) {
            int count = zis.read(data, offset, data_size - offset);
            if (count < 0) {  // read data is done
                break;
            }
            offset += count;

            if (entrySize >= 1 && offset >= entrySize) {  // we know the size and we're done
                break;
            }

            // if we don't know the entry size and we're not done reading,
            // expand the data buffer some more.
            if (offset >= data_size) {
                byte[] temp = new byte[data_size + block_size];
                System.arraycopy(data, 0, temp, 0, data_size);
                data_size += block_size;
                data = temp;
                block_size *= 2;
            }
        }

        if (offset < data_size) {
            // buffer was allocated too large, trim it
            byte[] temp = new byte[offset];
            if (offset > 0) {
                System.arraycopy(data, 0, temp, 0, offset);
            }
            data = temp;
        }

        return data;
    }

    /**
     * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name.
     * @param className the fully-qualified name of the class to return.
     * @throws ClassNotFoundException
     */
    @Override
    public IClassDescriptor getClass(String className) throws ClassNotFoundException {
        try {
            return new ClassWrapper(loadClass(className));
        } catch (ClassNotFoundException e) {
            throw e;  // useful for debugging
        }
    }
}
