/*
 * Copyright (C) 2012 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 com.android.tools.lint.checks;

import static com.android.SdkConstants.ANDROID_PKG;
import static com.android.SdkConstants.DOT_XML;
import static com.android.tools.lint.detector.api.LintUtils.assertionsEnabled;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.repository.api.LocalPackage;
import com.android.sdklib.repositoryv2.AndroidSdkHandler;
import com.android.tools.lint.client.api.LintClient;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.utils.Pair;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.ByteSink;
import com.google.common.io.Files;
import com.google.common.primitives.UnsignedBytes;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Database for API checking: Allows quick lookup of a given class, method or field
 * to see which API level it was introduced in.
 * <p>
 * This class is optimized for quick bytecode lookup used in conjunction with the
 * ASM library: It has lookup methods that take internal JVM signatures, and for a method
 * call for example it processes the owner, name and description parameters separately
 * the way they are provided from ASM.
 * <p>
 * The {@link Api} class provides access to the full Android API along with version
 * information, initialized from an XML file. This lookup class adds a binary cache around
 * the API to make initialization faster and to require fewer objects. It creates
 * a binary cache data structure, which fits in a single byte array, which means that
 * to open the database you can just read in the byte array and go. On one particular
 * machine, this takes about 30-50 ms versus 600-800ms for the full parse. It also
 * helps memory by placing everything in a compact byte array instead of needing separate
 * strings (2 bytes per character in a char[] for the 25k method entries, 11k field entries
 * and 6k class entries) - and it also avoids the same number of Map.Entry objects.
 * When creating the memory data structure it performs a few other steps to help memory:
 * <ul>
 * <li> It stores the strings as single bytes, since all the JVM signatures are in ASCII
 * <li> It strips out the method return types (which takes the binary size down from
 *      about 4.7M to 4.0M)
 * <li> It strips out all APIs that have since=1, since the lookup only needs to find
 *      classes, methods and fields that have an API level *higher* than 1. This drops
 *      the memory use down from 4.0M to 1.7M.
 * </ul>
 */
public class ApiLookup {
    /** Relative path to the api-versions.xml database file within the Lint installation */
    private static final String XML_FILE_PATH = "platform-tools/api/api-versions.xml"; //$NON-NLS-1$
    private static final String FILE_HEADER = "API database used by Android lint\000";
    private static final int BINARY_FORMAT_VERSION = 8;
    private static final boolean DEBUG_SEARCH = false;
    private static final boolean WRITE_STATS = false;

    private static final int CLASS_HEADER_MEMBER_OFFSETS = 1;
    private static final int CLASS_HEADER_API = 2;
    private static final int CLASS_HEADER_DEPRECATED = 3;
    private static final int CLASS_HEADER_INTERFACES = 4;
    private static final int HAS_DEPRECATION_BYTE_FLAG = 1 << 7;
    private static final int API_MASK = ~HAS_DEPRECATION_BYTE_FLAG;

    @VisibleForTesting
    static final boolean DEBUG_FORCE_REGENERATE_BINARY = false;

    private final Api mInfo;
    private byte[] mData;
    private int[] mIndices;

    private static WeakReference<ApiLookup> sInstance = new WeakReference<ApiLookup>(null);

    private int mPackageCount;

    /**
     * Returns an instance of the API database
     *
     * @param client the client to associate with this database - used only for
     *            logging. The database object may be shared among repeated invocations,
     *            and in that case client used will be the one originally passed in.
     *            In other words, this parameter may be ignored if the client created
     *            is not new.
     * @return a (possibly shared) instance of the API database, or null
     *         if its data can't be found
     */
    @Nullable
    public static ApiLookup get(@NonNull LintClient client) {
        synchronized (ApiLookup.class) {
            ApiLookup db = sInstance.get();
            if (db == null) {
                File file = client.findResource(XML_FILE_PATH);
                if (file == null) {
                    // AOSP build environment?
                    String build = System.getenv("ANDROID_BUILD_TOP");   //$NON-NLS-1$
                    if (build != null) {
                        file = new File(build, "development/sdk/api-versions.xml" //$NON-NLS-1$
                                .replace('/', File.separatorChar));
                    }
                }

                if (file == null || !file.exists()) {
                    return null;
                } else {
                    db = get(client, file);
                }
                sInstance = new WeakReference<ApiLookup>(db);
            }

            return db;
        }
    }

    @VisibleForTesting
    @Nullable
    static String getPlatformVersion(@NonNull LintClient client) {
        AndroidSdkHandler sdk = client.getSdk();
        if (sdk != null) {
            LocalPackage pkgInfo = sdk
                    .getLocalPackage(SdkConstants.FD_PLATFORM_TOOLS, client.getRepositoryLogger());
            if (pkgInfo != null) {
                return pkgInfo.getVersion().toShortString();
            }
        }
        return null;
    }

    @VisibleForTesting
    @NonNull
    static String getCacheFileName(@NonNull String xmlFileName, @Nullable String platformVersion) {
        if (LintUtils.endsWith(xmlFileName, DOT_XML)) {
            xmlFileName = xmlFileName.substring(0, xmlFileName.length() - DOT_XML.length());
        }

        StringBuilder sb = new StringBuilder(100);
        sb.append(xmlFileName);

        // Incorporate version number in the filename to avoid upgrade filename
        // conflicts on Windows (such as issue #26663)
        sb.append('-').append(BINARY_FORMAT_VERSION);

        if (platformVersion != null) {
            sb.append('-').append(platformVersion);
        }

        sb.append(".bin"); //$NON-NLS-1$
        return sb.toString();
    }

    /**
     * Returns an instance of the API database
     *
     * @param client the client to associate with this database - used only for
     *            logging
     * @param xmlFile the XML file containing configuration data to use for this
     *            database
     * @return a (possibly shared) instance of the API database, or null
     *         if its data can't be found
     */
    private static ApiLookup get(LintClient client, File xmlFile) {
        if (!xmlFile.exists()) {
            client.log(null, "The API database file %1$s does not exist", xmlFile);
            return null;
        }

        File cacheDir = client.getCacheDir(true/*create*/);
        if (cacheDir == null) {
            cacheDir = xmlFile.getParentFile();
        }

        String platformVersion = getPlatformVersion(client);
        File binaryData = new File(cacheDir, getCacheFileName(xmlFile.getName(), platformVersion));

        if (DEBUG_FORCE_REGENERATE_BINARY) {
            System.err.println("\nTemporarily regenerating binary data unconditionally \nfrom "
                    + xmlFile + "\nto " + binaryData);
            if (!createCache(client, xmlFile, binaryData)) {
                return null;
            }
        } else if (!binaryData.exists() || binaryData.lastModified() < xmlFile.lastModified()
               || binaryData.length() == 0) {
            if (!createCache(client, xmlFile, binaryData)) {
                return null;
            }
        }

        if (!binaryData.exists()) {
            client.log(null, "The API database file %1$s does not exist", binaryData);
            return null;
        }

        return new ApiLookup(client, xmlFile, binaryData, null);
    }

    private static boolean createCache(LintClient client, File xmlFile, File binaryData) {
        long begin = 0;
        if (WRITE_STATS) {
            begin = System.currentTimeMillis();
        }

        Api info = Api.parseApi(xmlFile);

        if (WRITE_STATS) {
            long end = System.currentTimeMillis();
            System.out.println("Reading XML data structures took " + (end - begin) + " ms)");
        }

        if (info != null) {
            try {
                writeDatabase(binaryData, info);
                return true;
            } catch (IOException ioe) {
                client.log(ioe, "Can't write API cache file");
            }
        }

        return false;
    }

    /** Use one of the {@link #get} factory methods instead */
    private ApiLookup(
            @NonNull LintClient client,
            @NonNull File xmlFile,
            @Nullable File binaryFile,
            @Nullable Api info) {
        mInfo = info;

        if (binaryFile != null) {
            readData(client, xmlFile, binaryFile);
        }
    }

    /**
     * Database format:
     * <pre>
     * (Note: all numbers are big endian; the format uses 1, 2, 3 and 4 byte integers.)
     *
     *
     * 1. A file header, which is the exact contents of {@link #FILE_HEADER} encoded
     *     as ASCII characters. The purpose of the header is to identify what the file
     *     is for, for anyone attempting to open the file.
     * 2. A file version number. If the binary file does not match the reader's expected
     *     version, it can ignore it (and regenerate the cache from XML).
     *
     * 3. The index table. When the data file is read, this is used to initialize the
     *    {@link #mIndices} array. The index table is built up like this:
     *    a. The number of index entries (e.g. number of elements in the {@link #mIndices} array)
     *        [1 4-byte int]
     *    b. The number of java/javax packages [1 4 byte int]
     *    c. Offsets to the package entries, one for each package, and each offset is 4 bytes.
     *    d. Offsets to the class entries, one for each class, and each offset is 4 bytes.
     *    e. Offsets to the member entries, one for each member, and each offset is 4 bytes.
     *
     * 4. The member entries -- one for each member. A given class entry will point to the
     *    first and last members in the index table above, and the offset of a given member
     *    is pointing to the offset of these entries.
     *    a. The name and description (except for the return value) of the member, in JVM format
     *       (e.g. for toLowerCase(char) we'd have "toLowerCase(C)". This is converted into
     *       UTF_8 representation as bytes [n bytes, the length of the byte representation of
     *       the description).
     *    b. A terminating 0 byte [1 byte].
     *    c. The API level the member was introduced in [1 byte], BUT with the
     *       top bit ({@link #HAS_DEPRECATION_BYTE_FLAG}) set if the member is deprecated.
     *    d. IF the member is deprecated, the API level the member was deprecated in [1 byte].
     *       Note that this byte does not appear if the bit indicated in (c) is not set.
     *
     * 5. The class entries -- one for each class.
     *    a. The index within this class entry where the metadata (other than the name)
     *       can be found. [1 byte]. This means that if you know a class by its number,
     *       you can quickly jump to its metadata without scanning through the string to
     *       find the end of it, by just adding this byte to the current offset and
     *       then you're at the data described below for (d).
     *    b. The name of the class (just the base name, not the package), as encoded as a
     *       UTF-8 string. [n bytes]
     *    c. A terminating 0 [1 byte].
     *    d. The index in the index table (3) of the first member in the class [a 3 byte integer.]
     *    e. The number of members in the class [a 2 byte integer].
     *    f. The API level the class was introduced in [1 byte], BUT with the
     *       top bit ({@link #HAS_DEPRECATION_BYTE_FLAG}) set if the class is deprecated.
     *    g. IF the class is deprecated, the API level the class was deprecated in [1 byte].
     *       Note that this byte does not appear if the bit indicated in (f) is not set.
     *    h. The number of new super classes and interfaces [1 byte]. This counts only
     *       super classes and interfaces added after the original API level of the class.
     *    i. For each super class or interface counted in h,
     *       I. The index of the class [a 3 byte integer]
     *       II. The API level the class/interface was added [1 byte]
     *
     * 6. The package entries -- one for each package.
     *    a. The name of the package as encoded as a UTF-8 string. [n bytes]
     *    b. A terminating 0 [1 byte].
     *    c. The index in the index table (3) of the first class in the package [a 3 byte integer.]
     *    d. The number of classes in the package [a 2 byte integer].
     * </pre>
     */
    private void readData(@NonNull LintClient client, @NonNull File xmlFile,
            @NonNull File binaryFile) {
        if (!binaryFile.exists()) {
            client.log(null, "%1$s does not exist", binaryFile);
            return;
        }
        long start = System.currentTimeMillis();
        try {
            byte[] b = Files.toByteArray(binaryFile);

            // First skip the header
            int offset = 0;
            byte[] expectedHeader = FILE_HEADER.getBytes(Charsets.US_ASCII);
            for (byte anExpectedHeader : expectedHeader) {
                if (anExpectedHeader != b[offset++]) {
                    client.log(null, "Incorrect file header: not an API database cache " +
                            "file, or a corrupt cache file");
                    return;
                }
            }

            // Read in the format number
            if (b[offset++] != BINARY_FORMAT_VERSION) {
                // Force regeneration of new binary data with up to date format
                if (createCache(client, xmlFile, binaryFile)) {
                    readData(client, xmlFile, binaryFile); // Recurse
                }

                return;
            }

            int indexCount = get4ByteInt(b, offset);
            offset += 4;
            mPackageCount = get4ByteInt(b, offset);
            offset += 4;

            mIndices = new int[indexCount];
            for (int i = 0; i < indexCount; i++) {
                // TODO: Pack the offsets: They increase by a small amount for each entry, so
                // no need to spend 4 bytes on each. These will need to be processed when read
                // back in anyway, so consider storing the offset -deltas- as single bytes and
                // adding them up cumulatively in readData().
                mIndices[i] = get4ByteInt(b, offset);
                offset += 4;
            }
            mData = b;
            // TODO: We only need to keep the data portion here since we've initialized
            // the offset array separately.
            // TODO: Investigate (profile) accessing the byte buffer directly instead of
            // accessing a byte array.
        } catch (Throwable e) {
            client.log(null, "Failure reading binary cache file %1$s", binaryFile.getPath());
            client.log(null, "Please delete the file and restart the IDE/lint: %1$s",
                    binaryFile.getPath());
            client.log(e, null);
        }
        if (WRITE_STATS) {
            long end = System.currentTimeMillis();
            System.out.println("\nRead API database in " + (end - start)
                    + " milliseconds.");
            System.out.println("Size of data table: " + mData.length + " bytes ("
                    + Integer.toString(mData.length / 1024) + "k)\n");
        }
    }

    /** See the {@link #readData(LintClient,File,File)} for documentation on the data format. */
    private static void writeDatabase(File file, Api info) throws IOException {
        Map<String, ApiClass> classMap = info.getClasses();

        List<ApiPackage> packages = Lists.newArrayList(info.getPackages().values());
        Collections.sort(packages);

        // Compute members of each class that must be included in the database; we can
        // skip those that have the same since-level as the containing class. And we
        // also need to keep those entries that are marked deprecated.
        int estimatedSize = 0;
        for (ApiPackage pkg : packages) {
            estimatedSize += 4; // offset entry
            estimatedSize += pkg.getName().length() + 20; // package entry

            if (assertionsEnabled() && !isRelevantOwner(pkg.getName() + "/") &&
                    !pkg.getName().startsWith("android/support")) {
                System.out.println("Warning: isRelevantOwner fails for " + pkg.getName() + "/");
            }

            for (ApiClass apiClass : pkg.getClasses()) {
                estimatedSize += 4; // offset entry
                estimatedSize += apiClass.getName().length() + 20; // class entry

                Set<String> allMethods = apiClass.getAllMethods(info);
                Set<String> allFields = apiClass.getAllFields(info);
                // Strip out all members that have been supported since version 1.
                // This makes the database *much* leaner (down from about 4M to about
                // 1.7M), and this just fills the table with entries that ultimately
                // don't help the API checker since it just needs to know if something
                // requires a version *higher* than the minimum. If in the future the
                // database needs to answer queries about whether a method is public
                // or not, then we'd need to put this data back in.
                int clsSince = apiClass.getSince();
                List<String> members = new ArrayList<String>(allMethods.size() + allFields.size());
                for (String member : allMethods) {
                    if (apiClass.getMethod(member, info) != clsSince
                            || apiClass.getMemberDeprecatedIn(member, info) > 0) {
                        members.add(member);
                    }
                }
                for (String member : allFields) {
                    if (apiClass.getField(member, info) != clsSince
                            || apiClass.getMemberDeprecatedIn(member, info) > 0) {
                        members.add(member);
                    }
                }

                estimatedSize += 2 + 4 * (apiClass.getInterfaces().size());
                if (apiClass.getSuperClasses().size() > 1) {
                    estimatedSize += 2 + 4 * (apiClass.getSuperClasses().size());
                }

                // Only include classes that have one or more members requiring version 2 or higher:
                Collections.sort(members);
                apiClass.members = members;
                for (String member : members) {
                    estimatedSize += member.length();
                    estimatedSize += 16;
                }
            }

            // Ensure the classes are sorted
            Collections.sort(pkg.getClasses());
        }

        // Write header
        ByteBuffer buffer = ByteBuffer.allocate(estimatedSize);
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.put(FILE_HEADER.getBytes(Charsets.US_ASCII));
        buffer.put((byte) BINARY_FORMAT_VERSION);

        int indexCountOffset = buffer.position();
        int indexCount = 0;

        buffer.putInt(0); // placeholder

        // Write the number of packages in the package index
        buffer.putInt(packages.size());

        // Write package index
        int newIndex = buffer.position();
        for (ApiPackage pkg : packages) {
            pkg.indexOffset = newIndex;
            newIndex += 4;
            indexCount++;
        }

        // Write class index
        for (ApiPackage pkg : packages) {
            for (ApiClass cls : pkg.getClasses()) {
                cls.indexOffset = newIndex;
                cls.index = indexCount;
                newIndex += 4;
                indexCount++;
            }
        }

        // Write member indices
        for (ApiPackage pkg : packages) {
            for (ApiClass cls : pkg.getClasses()) {
                if (cls.members != null && !cls.members.isEmpty()) {
                    cls.memberOffsetBegin = newIndex;
                    cls.memberIndexStart = indexCount;
                    for (String ignored : cls.members) {
                        newIndex += 4;
                        indexCount++;
                    }
                    cls.memberOffsetEnd = newIndex;
                    cls.memberIndexLength = indexCount - cls.memberIndexStart;
                } else {
                    cls.memberOffsetBegin = -1;
                    cls.memberOffsetEnd = -1;
                    cls.memberIndexStart = -1;
                    cls.memberIndexLength = 0;
                }
            }
        }

        // Fill in the earlier index count
        buffer.position(indexCountOffset);
        buffer.putInt(indexCount);
        buffer.position(newIndex);

        // Write member entries
        for (ApiPackage pkg : packages) {
            for (ApiClass apiClass : pkg.getClasses()) {
                String clz = apiClass.getName();
                int index = apiClass.memberOffsetBegin;
                for (String member : apiClass.members) {
                    // Update member offset to point to this entry
                    int start = buffer.position();
                    buffer.position(index);
                    buffer.putInt(start);
                    index = buffer.position();
                    buffer.position(start);

                    int since;
                    if (member.indexOf('(') != -1) {
                        since = apiClass.getMethod(member, info);
                    } else {
                        since = apiClass.getField(member, info);
                    }
                    if (since == Integer.MAX_VALUE) {
                        assert false : clz + ':' + member;
                        since = 1;
                    }

                    int deprecatedIn = apiClass.getMemberDeprecatedIn(member, info);
                    if (deprecatedIn != 0) {
                        assert deprecatedIn != -1 : deprecatedIn + " for " + member;
                    }

                    byte[] signature = member.getBytes(Charsets.UTF_8);
                    for (byte b : signature) {
                        // Make sure all signatures are really just simple ASCII
                        assert b == (b & 0x7f) : member;
                        buffer.put(b);
                        // Skip types on methods
                        if (b == (byte) ')') {
                            break;
                        }
                    }
                    buffer.put((byte) 0);
                    int api = since;
                    assert api == UnsignedBytes.toInt((byte) api);
                    assert api >= 1 && api < 0xFF; // max that fits in a byte

                    boolean isDeprecated = deprecatedIn > 0;
                    if (isDeprecated) {
                        api |= HAS_DEPRECATION_BYTE_FLAG;
                    }

                    buffer.put((byte) api);

                    if (isDeprecated) {
                        assert deprecatedIn == UnsignedBytes.toInt((byte) deprecatedIn);
                        buffer.put((byte) deprecatedIn);
                    }
                }
                assert index == apiClass.memberOffsetEnd : apiClass.memberOffsetEnd;
            }
        }

        // Write class entries. These are written together, rather than
        // being spread out among the member entries, in order to have
        // reference locality (search that a binary search through the classes
        // are likely to look at entries near each other.)
        for (ApiPackage pkg : packages) {
            List<ApiClass> classes = pkg.getClasses();
            for (ApiClass cls : classes) {
                int index = buffer.position();
                buffer.position(cls.indexOffset);
                buffer.putInt(index);
                buffer.position(index);
                String name = cls.getSimpleName();

                byte[] nameBytes = name.getBytes(Charsets.UTF_8);
                assert nameBytes.length < 254 : name;
                buffer.put((byte)(nameBytes.length + 2)); // 2: terminating 0, and this byte itself
                buffer.put(nameBytes);
                buffer.put((byte) 0);

                // 3 bytes for beginning, 2 bytes for *length*
                put3ByteInt(buffer, cls.memberIndexStart);
                put2ByteInt(buffer, cls.memberIndexLength);

                ApiClass apiClass = classMap.get(cls.getName());
                assert apiClass != null : cls.getName();
                int since = apiClass.getSince();
                assert since == UnsignedBytes.toInt((byte) since) : since; // make sure it fits
                int deprecatedIn = apiClass.getDeprecatedIn();
                boolean isDeprecated = deprecatedIn > 0;
                // The first byte is deprecated in
                if (isDeprecated) {
                    since |= HAS_DEPRECATION_BYTE_FLAG;
                    assert since == UnsignedBytes.toInt((byte) since) : since; // make sure it fits
                }
                buffer.put((byte) since);
                if (isDeprecated) {
                    assert deprecatedIn == UnsignedBytes.toInt((byte) deprecatedIn) : deprecatedIn;
                    buffer.put((byte) deprecatedIn);
                }

                List<Pair<String, Integer>> interfaces = apiClass.getInterfaces();
                int count = 0;
                if (interfaces != null && !interfaces.isEmpty()) {
                    for (Pair<String, Integer> pair : interfaces) {
                        int api = pair.getSecond();
                        if (api > apiClass.getSince()) {
                            count++;
                        }
                    }
                }
                List<Pair<String, Integer>> supers = apiClass.getSuperClasses();
                if (supers != null && !supers.isEmpty()) {
                    for (Pair<String, Integer> pair : supers) {
                        int api = pair.getSecond();
                        if (api > apiClass.getSince()) {
                            count++;
                        }
                    }
                }
                buffer.put((byte)count);
                if (count > 0) {
                    if (supers != null) {
                        for (Pair<String, Integer> pair : supers) {
                            int api = pair.getSecond();
                            if (api > apiClass.getSince()) {
                                ApiClass superClass = classMap.get(pair.getFirst());
                                assert superClass != null : cls;
                                put3ByteInt(buffer, superClass.index);
                                buffer.put((byte) api);
                            }
                        }
                    }
                    if (interfaces != null) {
                        for (Pair<String, Integer> pair : interfaces) {
                            int api = pair.getSecond();
                            if (api > apiClass.getSince()) {
                                ApiClass interfaceClass = classMap.get(pair.getFirst());
                                assert interfaceClass != null : cls;
                                put3ByteInt(buffer, interfaceClass.index);
                                buffer.put((byte) api);
                            }
                        }
                    }
                }
            }
        }

        for (ApiPackage pkg : packages) {
            int index = buffer.position();
            buffer.position(pkg.indexOffset);
            buffer.putInt(index);
            buffer.position(index);

            byte[] bytes = pkg.getName().getBytes(Charsets.UTF_8);
            buffer.put(bytes);
            buffer.put((byte)0);

            List<ApiClass> classes = pkg.getClasses();
            if (classes.isEmpty()) {
                put3ByteInt(buffer, 0);
                put2ByteInt(buffer, 0);
            } else {
                // 3 bytes for beginning, 2 bytes for *length*
                int firstClassIndex = classes.get(0).index;
                int classCount = classes.get(classes.size() - 1).index - firstClassIndex + 1;
                put3ByteInt(buffer, firstClassIndex);
                put2ByteInt(buffer, classCount);
            }
        }

        int size = buffer.position();
        assert size <= buffer.limit();
        buffer.mark();

        if (WRITE_STATS) {
            System.out.print("Actual binary size: " + size + " bytes");
            System.out.println(String.format(" (%.1fM)", size/(1024*1024.f)));
        }

        // Now dump this out as a file
        // There's probably an API to do this more efficiently; TODO: Look into this.
        byte[] b = new byte[size];
        buffer.rewind();
        buffer.get(b);
        if (file.exists()) {
            boolean deleted = file.delete();
            assert deleted : file;
        }
        ByteSink sink = Files.asByteSink(file);
        sink.write(b);
    }

    // For debugging only
    private String dumpEntry(int offset) {
        if (DEBUG_SEARCH) {
            StringBuilder sb = new StringBuilder(200);
            for (int i = offset; i < mData.length; i++) {
                if (mData[i] == 0) {
                    break;
                }
                char c = (char) UnsignedBytes.toInt(mData[i]);
                sb.append(c);
            }

            return sb.toString();
        } else {
            return "<disabled>"; //$NON-NLS-1$
        }
    }

    private static int compare(byte[] data, int offset, byte terminator, String s, int sOffset,
            int max) {
        int i = offset;
        int j = sOffset;
        for (; j < max; i++, j++) {
            byte b = data[i];
            char c = s.charAt(j);
            // TODO: Check somewhere that the strings are purely in the ASCII range; if not
            // they're not a match in the database
            byte cb = (byte) c;
            int delta = b - cb;
            if (delta != 0) {
                return delta;
            }
        }

        return data[i] - terminator;
    }

    /**
     * Returns the API version required by the given class reference,
     * or -1 if this is not a known API class. Note that it may return -1
     * for classes introduced in version 1; internally the database only
     * stores version data for version 2 and up.
     *
     * @param className the internal name of the class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @return the minimum API version the method is supported for, or -1 if
     *         it's unknown <b>or version 1</b>.
     */
    public int getClassVersion(@NonNull String className) {
        //noinspection VariableNotUsedInsideIf
        if (mData != null) {
            return getClassVersion(findClass(className));
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(className);
            if (clz != null) {
                int since = clz.getSince();
                if (since == Integer.MAX_VALUE) {
                    since = -1;
                }
                return since;
            }
        }

        return -1;
    }

    /**
     * Returns true if the given owner class is known in the API database.
     *
     * @param className the internal name of the class, e.g. its fully qualified name (as returned
     *                  by Class.getName(), but with '.' replaced by '/' (and '$' for inner
     *                  classes)
     * @return true if this is a class found in the API database
     */
    public boolean isKnownClass(@NonNull String className) {
        return findClass(className) != -1;
    }

    private int getClassVersion(int classNumber) {
        if (classNumber != -1) {
            int offset = seekClassData(classNumber, CLASS_HEADER_API);
            int api = UnsignedBytes.toInt(mData[offset]) & API_MASK;
            return api > 1 ? api : -1;
        }
        return -1;
    }

    /**
     * Returns the API version required to perform the given cast, or -1 if this is valid for all
     * versions of the class (or, if these are not known classes or if the cast is not valid at
     * all.) <p> Note also that this method should only be called for interfaces that are actually
     * implemented by this class or extending the given super class (check elsewhere); it doesn't
     * distinguish between interfaces implemented in the initial version of the class and interfaces
     * not implemented at all.
     *
     * @param sourceClass      the internal name of the class, e.g. its fully qualified name (as
     *                         returned by Class.getName(), but with '.' replaced by '/'.
     * @param destinationClass the class to cast the sourceClass to
     * @return the minimum API version the method is supported for, or 1 or -1 if it's unknown.
     */
    public int getValidCastVersion(@NonNull String sourceClass,
            @NonNull String destinationClass) {
        if (mData != null) {
            int classNumber = findClass(sourceClass);
            if (classNumber != -1) {
                int interfaceNumber = findClass(destinationClass);
                if (interfaceNumber != -1) {
                    int offset = seekClassData(classNumber, CLASS_HEADER_INTERFACES);
                    int interfaceCount = mData[offset++];
                    for (int i = 0; i < interfaceCount; i++) {
                        int clsNumber = get3ByteInt(mData, offset);
                        offset += 3;
                        int api = mData[offset++];
                        if (clsNumber == interfaceNumber) {
                           return api;
                        }
                    }
                    return getClassVersion(classNumber);
                }
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(sourceClass);
            if (clz != null) {
                List<Pair<String, Integer>> interfaces = clz.getInterfaces();
                for (Pair<String,Integer> pair : interfaces) {
                    String interfaceName = pair.getFirst();
                    if (interfaceName.equals(destinationClass)) {
                        return pair.getSecond();
                    }
                }
            }
        }

        return -1;
    }
    /**
     * Returns the API version the given class was deprecated in, or -1 if the class
     * is not deprecated.
     *
     * @param className the internal name of the method's owner class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @return the API version the API was deprecated in, or -1 if
     *         it's unknown <b>or version 0</b>.
     */
    public int getClassDeprecatedIn(@NonNull String className) {
        if (mData != null) {
            int classNumber = findClass(className);
            if (classNumber != -1) {
                int offset = seekClassData(classNumber, CLASS_HEADER_DEPRECATED);
                if (offset == -1) {
                    // Not deprecated
                    return -1;
                }
                int deprecatedIn = UnsignedBytes.toInt(mData[offset]);
                return deprecatedIn != 0 ? deprecatedIn : -1;
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(className);
            if (clz != null) {
                int deprecatedIn = clz.getDeprecatedIn();
                if (deprecatedIn == Integer.MAX_VALUE) {
                    deprecatedIn = -1;
                }
                return deprecatedIn;
            }
        }

        return -1;
    }

    /**
     * Returns the API version required by the given method call. The method is
     * referred to by its {@code owner}, {@code name} and {@code desc} fields.
     * If the method is unknown it returns -1. Note that it may return -1 for
     * classes introduced in version 1; internally the database only stores
     * version data for version 2 and up.
     *
     * @param owner the internal name of the method's owner class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @param name the method's name
     * @param desc the method's descriptor - see {@link org.objectweb.asm.Type}
     * @return the minimum API version the method is supported for, or 1 or -1 if
     *         it's unknown.
     */
    public int getCallVersion(
            @NonNull String owner,
            @NonNull String name,
            @NonNull String desc) {
        //noinspection VariableNotUsedInsideIf
        if (mData != null) {
            int classNumber = findClass(owner);
            if (classNumber != -1) {
                int api = findMember(classNumber, name, desc);
                if (api == -1) {
                    return getClassVersion(classNumber);
                }
                return api;
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(owner);
            if (clz != null) {
                String signature = name + desc;
                int since = clz.getMethod(signature, mInfo);
                if (since == Integer.MAX_VALUE) {
                    since = -1;
                }
                return since;
            }
        }

        return -1;
    }

    /**
     * Returns the API version the given call was deprecated in, or -1 if the method
     * is not deprecated.
     *
     * @param owner the internal name of the method's owner class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @param name the method's name
     * @param desc the method's descriptor - see {@link org.objectweb.asm.Type}
     * @return the API version the API was deprecated in, or 1 or -1 if
     *         it's unknown.
     */
    public int getCallDeprecatedIn(
            @NonNull String owner,
            @NonNull String name,
            @NonNull String desc) {
        //noinspection VariableNotUsedInsideIf
        if (mData != null) {
            int classNumber = findClass(owner);
            if (classNumber != -1) {
                int deprecatedIn = findMemberDeprecatedIn(classNumber, name, desc);
                return deprecatedIn != 0 ? deprecatedIn : -1;
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(owner);
            if (clz != null) {
                String signature = name + desc;
                int deprecatedIn = clz.getMemberDeprecatedIn(signature, mInfo);
                if (deprecatedIn == Integer.MAX_VALUE) {
                    deprecatedIn = -1;
                }
                return deprecatedIn;
            }
        }

        return -1;
    }

    /**
     * Returns the API version required to access the given field, or -1 if this
     * is not a known API method. Note that it may return -1 for classes
     * introduced in version 1; internally the database only stores version data
     * for version 2 and up.
     *
     * @param owner the internal name of the method's owner class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @param name the method's name
     * @return the minimum API version the method is supported for, or 1 or -1 if
     *         it's unknown.
     */
    public int getFieldVersion(
            @NonNull String owner,
            @NonNull String name) {
        //noinspection VariableNotUsedInsideIf
        if (mData != null) {
            int classNumber = findClass(owner);
            if (classNumber != -1) {
                int api = findMember(classNumber, name, null);
                if (api == -1) {
                    return getClassVersion(classNumber);
                }
                return api;
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(owner);
            if (clz != null) {
                int since = clz.getField(name, mInfo);
                if (since == Integer.MAX_VALUE) {
                    since = -1;
                }
                return since;
            }
        }

        return -1;
    }

    /**
     * Returns the API version the given field was deprecated in, or -1 if the field
     * is not deprecated.
     *
     * @param owner the internal name of the method's owner class, e.g. its
     *            fully qualified name (as returned by Class.getName(), but with
     *            '.' replaced by '/'.
     * @param name the method's name
     * @return the API version the API was deprecated in, or 1 or -1 if
     *         it's unknown.
     */
    public int getFieldDeprecatedIn(
            @NonNull String owner,
            @NonNull String name) {
        //noinspection VariableNotUsedInsideIf
        if (mData != null) {
            int classNumber = findClass(owner);
            if (classNumber != -1) {
                int deprecatedIn = findMemberDeprecatedIn(classNumber, name, null);
                return deprecatedIn != 0 ? deprecatedIn : -1;
            }
        }  else {
            assert mInfo != null;
            ApiClass clz = mInfo.getClass(owner);
            if (clz != null) {
                int deprecatedIn = clz.getMemberDeprecatedIn(name, mInfo);
                if (deprecatedIn == Integer.MAX_VALUE) {
                    deprecatedIn = -1;
                }
                return deprecatedIn;
            }
        }

        return -1;
    }

    /**
     * Returns true if the given owner (in VM format) is relevant to the database.
     * This allows quick filtering out of owners that won't return any data
     * for the various {@code #getFieldVersion} etc methods.
     *
     * @param owner the owner to look up
     * @return true if the owner might be relevant to the API database
     */
    public static boolean isRelevantOwner(@NonNull String owner) {
        if (owner.startsWith("java")) {                   //$NON-NLS-1$ // includes javax/
            return true;
        }
        if (owner.startsWith(ANDROID_PKG)) {
            return !owner.startsWith("/support/", 7);
        } else if (owner.startsWith("org/")) {            //$NON-NLS-1$
            if (owner.startsWith("xml", 4)                //$NON-NLS-1$
                    || owner.startsWith("w3c/", 4)        //$NON-NLS-1$
                    || owner.startsWith("json/", 4)       //$NON-NLS-1$
                    || owner.startsWith("apache/", 4)) {  //$NON-NLS-1$
                return true;
            }
        } else if (owner.startsWith("com/")) {            //$NON-NLS-1$
            if (owner.startsWith("google/", 4)            //$NON-NLS-1$
                    || owner.startsWith("android/", 4)) { //$NON-NLS-1$
                return true;
            }
        } else if (owner.startsWith("junit")              //$NON-NLS-1$
                    || owner.startsWith("dalvik")) {      //$NON-NLS-1$
            return true;
        }

        return false;
    }

    /**
     * Returns true if the given owner (in VM format) is a valid Java package supported
     * in any version of Android.
     *
     * @param owner the package, in VM format
     * @return true if the package is included in one or more versions of Android
     */
    public boolean isValidJavaPackage(@NonNull String owner) {
        return findPackage(owner) != -1;
    }

    /** Returns the package index of the given class, or -1 if it is unknown */
    private int findPackage(@NonNull String owner) {
        assert owner.indexOf('.') == -1 : "Should use / instead of . in owner: " + owner;

        // The index array contains class indexes from 0 to classCount and
        //   member indices from classCount to mIndices.length.
        int low = 0;
        int high = mPackageCount - 1;
        // Compare the api info at the given index.
        int classNameLength = owner.lastIndexOf('/');
        while (low <= high) {
            int middle = (low + high) >>> 1;
            int offset = mIndices[middle];

            if (DEBUG_SEARCH) {
                System.out.println("Comparing string " + owner.substring(0, classNameLength)
                        + " with entry at " + offset + ": " + dumpEntry(offset));
            }

            int compare = compare(mData, offset, (byte) 0, owner, 0, classNameLength);
            if (compare == 0) {
                if (DEBUG_SEARCH) {
                    System.out.println("Found " + dumpEntry(offset));
                }
                return middle;
            }

            if (compare < 0) {
                low = middle + 1;
            } else if (compare > 0) {
                high = middle - 1;
            } else {
                assert false; // compare == 0 already handled above
                return -1;
            }
        }

        return -1;
    }

    private static int get4ByteInt(@NonNull byte[] data, int offset) {
        byte b1 = data[offset++];
        byte b2 = data[offset++];
        byte b3 = data[offset++];
        byte b4 = data[offset];
        // The byte data is always big endian.
        return (b1 & 0xFF) << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
    }

    private static void put3ByteInt(@NonNull ByteBuffer buffer, int value) {
        // Big endian
        byte b3 = (byte) (value & 0xFF);
        value >>>= 8;
        byte b2 = (byte) (value & 0xFF);
        value >>>= 8;
        byte b1 = (byte) (value & 0xFF);
        buffer.put(b1);
        buffer.put(b2);
        buffer.put(b3);
    }

    private static void put2ByteInt(@NonNull ByteBuffer buffer, int value) {
        // Big endian
        byte b2 = (byte) (value & 0xFF);
        value >>>= 8;
        byte b1 = (byte) (value & 0xFF);
        buffer.put(b1);
        buffer.put(b2);
    }

    private static int get3ByteInt(@NonNull byte[] mData, int offset) {
        byte b1 = mData[offset++];
        byte b2 = mData[offset++];
        byte b3 = mData[offset];
        // The byte data is always big endian.
        return (b1 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b3 & 0xFF);
    }

    private static int get2ByteInt(@NonNull byte[] data, int offset) {
        byte b1 = data[offset++];
        byte b2 = data[offset];
        // The byte data is always big endian.
        return (b1 & 0xFF) << 8 | (b2 & 0xFF);
    }

    /** Returns the class number of the given class, or -1 if it is unknown */
    private int findClass(@NonNull String owner) {
        assert owner.indexOf('.') == -1 : "Should use / instead of . in owner: " + owner;

        int packageNumber = findPackage(owner);
        if (packageNumber == -1) {
            return -1;
        }
        int curr = mIndices[packageNumber];
        while (mData[curr] != 0) {
            curr++;
        }
        curr++;

        // 3 bytes for first offset
        int low = get3ByteInt(mData, curr);
        curr += 3;

        int length = get2ByteInt(mData, curr);
        if (length == 0) {
            return -1;
        }
        int high = low + length - 1;
        int index = owner.lastIndexOf('/');
        int classNameLength = owner.length();
        while (low <= high) {
            int middle = (low + high) >>> 1;
            int offset = mIndices[middle];
            offset++; // skip the byte which points to the metadata after the name

            if (DEBUG_SEARCH) {
                System.out.println("Comparing string " + owner.substring(0, classNameLength)
                        + " with entry at " + offset + ": " + dumpEntry(offset));
            }

            int compare = compare(mData, offset, (byte) 0, owner, index + 1, classNameLength);
            if (compare == 0) {
                if (DEBUG_SEARCH) {
                    System.out.println("Found " + dumpEntry(offset));
                }
                return middle;
            }

            if (compare < 0) {
                low = middle + 1;
            } else if (compare > 0) {
                high = middle - 1;
            } else {
                assert false; // compare == 0 already handled above
                return -1;
            }
        }

        return -1;
    }

    private int findMember(int classNumber, @NonNull String name, @Nullable String desc) {
        return findMember(classNumber, name, desc, false);
    }

    private int findMemberDeprecatedIn(int classNumber, @NonNull String name,
            @Nullable String desc) {
        return findMember(classNumber, name, desc, true);
    }

    private int seekClassData(int classNumber, int field) {
        int offset = mIndices[classNumber];
        offset += mData[offset] & 0xFF;
        if (field == CLASS_HEADER_MEMBER_OFFSETS) {
            return offset;
        }
        offset += 5; // 3 bytes for start, 2 bytes for length
        if (field == CLASS_HEADER_API) {
            return offset;
        }
        boolean hasDeprecation = (mData[offset] & HAS_DEPRECATION_BYTE_FLAG) != 0;
        offset++;
        if (field == CLASS_HEADER_DEPRECATED) {
            return hasDeprecation ? offset : -1;
        } else if (hasDeprecation) {
            offset++;
        }
        assert field == CLASS_HEADER_INTERFACES;
        return offset;
    }

    private int findMember(int classNumber, @NonNull String name, @Nullable String desc,
            boolean deprecation) {
        int curr = seekClassData(classNumber, CLASS_HEADER_MEMBER_OFFSETS);

        // 3 bytes for first offset
        int low = get3ByteInt(mData, curr);
        curr += 3;

        int length = get2ByteInt(mData, curr);
        if (length == 0) {
            return -1;
        }
        int high = low + length - 1;

        while (low <= high) {
            int middle = (low + high) >>> 1;
            int offset = mIndices[middle];

            if (DEBUG_SEARCH) {
                System.out.println("Comparing string " + (name + ';' + desc) +
                        " with entry at " + offset + ": " + dumpEntry(offset));
            }

            int compare;
            if (desc != null) {
                // Method
                int nameLength = name.length();
                compare = compare(mData, offset, (byte) '(', name, 0, nameLength);
                if (compare == 0) {
                    offset += nameLength;
                    int argsEnd = desc.indexOf(')');
                    // Only compare up to the ) -- after that we have a return value in the
                    // input description, which isn't there in the database
                    compare = compare(mData, offset, (byte) ')', desc, 0, argsEnd);
                    if (compare == 0) {
                        if (DEBUG_SEARCH) {
                            System.out.println("Found " + dumpEntry(offset));
                        }

                        offset += argsEnd + 1;

                        if (mData[offset++] == 0) {
                            // Yes, terminated argument list: get the API level
                            int api = UnsignedBytes.toInt(mData[offset]);
                            if (deprecation) {
                                if ((api & HAS_DEPRECATION_BYTE_FLAG) != 0) {
                                    return UnsignedBytes.toInt(mData[offset + 1]);
                                } else {
                                    return -1;
                                }
                            } else {
                                return api & API_MASK;
                            }
                        }
                    }
                }
            } else {
                // Field
                int nameLength = name.length();
                compare = compare(mData, offset, (byte) 0, name, 0, nameLength);
                if (compare == 0) {
                    offset += nameLength;
                    if (mData[offset++] == 0) {
                        // Yes, terminated argument list: get the API level
                        int api = UnsignedBytes.toInt(mData[offset]);
                        if (deprecation) {
                            if ((api & HAS_DEPRECATION_BYTE_FLAG) != 0) {
                                return UnsignedBytes.toInt(mData[offset + 1]);
                            } else {
                                return -1;
                            }
                        } else {
                            return api & API_MASK;
                        }
                    }
                }
            }

            if (compare < 0) {
                low = middle + 1;
            } else if (compare > 0) {
                high = middle - 1;
            } else {
                assert false; // compare == 0 already handled above
                return -1;
            }
        }

        return -1;
    }

    /** Clears out any existing lookup instances */
    @VisibleForTesting
    static void dispose() {
        sInstance.clear();
    }
}
