/*
 * Copyright (C) 2011 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.dx.merge;

import com.android.dx.dex.SizeOf;
import com.android.dx.dex.TableOfContents;
import com.android.dx.io.ClassData;
import com.android.dx.io.ClassDef;
import com.android.dx.io.Code;
import com.android.dx.io.DexBuffer;
import com.android.dx.io.DexHasher;
import com.android.dx.io.FieldId;
import com.android.dx.io.MethodId;
import com.android.dx.io.ProtoId;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.logging.Logger;

/**
 * Combine two dex files into one.
 */
public final class DexMerger {
    private static final Logger logger = Logger.getLogger(DexMerger.class.getName());

    private final DexBuffer dexWriter = new DexBuffer();
    private final DexBuffer.Section headerWriter;
    private final DexBuffer.Section idsDefsWriter;
    private final DexBuffer.Section mapListWriter;
    private final DexBuffer.Section typeListWriter;
    private final DexBuffer.Section annotationSetRefListWriter;
    private final DexBuffer.Section annotationSetWriter;
    private final DexBuffer.Section classDataWriter;
    private final DexBuffer.Section codeWriter;
    private final DexBuffer.Section stringDataWriter;
    private final DexBuffer.Section debugInfoWriter;
    private final DexBuffer.Section annotationWriter;
    private final DexBuffer.Section encodedArrayWriter;
    private final DexBuffer.Section annotationsDirectoryWriter;
    private final TableOfContents contentsOut;

    private final DexBuffer dexA;
    private final DexBuffer dexB;
    private final IndexMap aIndexMap;
    private final IndexMap bIndexMap;
    private final InstructionTransformer aInstructionTransformer;
    private final InstructionTransformer bInstructionTransformer;

    public DexMerger(DexBuffer dexA, DexBuffer dexB) throws IOException {
        this.dexA = dexA;
        this.dexB = dexB;

        TableOfContents aContents = dexA.getTableOfContents();
        TableOfContents bContents = dexB.getTableOfContents();
        aIndexMap = new IndexMap(dexWriter, aContents);
        bIndexMap = new IndexMap(dexWriter, bContents);
        aInstructionTransformer = new InstructionTransformer(aIndexMap);
        bInstructionTransformer = new InstructionTransformer(bIndexMap);

        headerWriter = dexWriter.appendSection(SizeOf.HEADER_ITEM, "header");

        // All IDs and definitions sections
        int idsDefsMaxSize
                = (aContents.stringIds.size + bContents.stringIds.size) * SizeOf.STRING_ID_ITEM
                + (aContents.typeIds.size + bContents.typeIds.size) * SizeOf.TYPE_ID_ITEM
                + (aContents.protoIds.size + bContents.protoIds.size) * SizeOf.PROTO_ID_ITEM
                + (aContents.fieldIds.size + bContents.fieldIds.size) * SizeOf.MEMBER_ID_ITEM
                + (aContents.methodIds.size + bContents.methodIds.size) * SizeOf.MEMBER_ID_ITEM
                + (aContents.classDefs.size + bContents.classDefs.size) * SizeOf.CLASS_DEF_ITEM;
        idsDefsWriter = dexWriter.appendSection(idsDefsMaxSize, "ids defs");

        // data section
        contentsOut = dexWriter.getTableOfContents();
        contentsOut.dataOff = dexWriter.getLength();

        contentsOut.mapList.off = dexWriter.getLength();
        contentsOut.mapList.size = 1;
        mapListWriter = dexWriter.appendSection(SizeOf.UINT
                + (contentsOut.sections.length * SizeOf.MAP_ITEM), "map list");

        /*
         * TODO: several of these sections are far too large than they need to be.
         *
         * typeList: we don't deduplicate identical type lists. This should be fixed.
         *
         * classDataWriter: uleb references to code items are larger than
         *     expected. We should use old & new code_item section offsets to
         *     pick an appropriate blow up size
         *
         * stringDataWriter: this shouldn't have to be larger, but it is
         *
         * encodedArrayWriter: this shouldn't have to be larger, but it is
         */

        contentsOut.typeLists.off = dexWriter.getLength();
        contentsOut.typeLists.size = 0;
        int maxTypeListBytes = aContents.typeLists.byteCount + bContents.typeLists.byteCount;
        typeListWriter = dexWriter.appendSection(maxTypeListBytes * 5, "type list");

        contentsOut.annotationSetRefLists.off = dexWriter.getLength();
        contentsOut.annotationSetRefLists.size = 0;
        annotationSetRefListWriter = dexWriter.appendSection(SizeOf.UINT, "annotation set ref list");

        contentsOut.annotationSets.off = dexWriter.getLength();
        contentsOut.annotationSets.size = 0;
        annotationSetWriter = dexWriter.appendSection(SizeOf.UINT, "annotation set");

        contentsOut.classDatas.off = dexWriter.getLength();
        contentsOut.classDatas.size = 0;
        int maxClassDataBytes = aContents.classDatas.byteCount + bContents.classDatas.byteCount;
        classDataWriter = dexWriter.appendSection(maxClassDataBytes * 2, "class data");

        contentsOut.codes.off = dexWriter.getLength();
        contentsOut.codes.size = 0;
        int maxCodeBytes = aContents.codes.byteCount + bContents.codes.byteCount;
        codeWriter = dexWriter.appendSection(maxCodeBytes, "code");

        contentsOut.stringDatas.off = dexWriter.getLength();
        contentsOut.stringDatas.size = 0;
        int maxStringDataBytes = aContents.stringDatas.byteCount
                + bContents.stringDatas.byteCount;
        stringDataWriter = dexWriter.appendSection(maxStringDataBytes * 2, "string data");

        contentsOut.debugInfos.off = dexWriter.getLength();
        contentsOut.debugInfos.size = 0;
        int maxDebugInfoBytes = aContents.debugInfos.byteCount + bContents.debugInfos.byteCount;
        debugInfoWriter = dexWriter.appendSection(maxDebugInfoBytes, "debug info");

        contentsOut.annotations.off = dexWriter.getLength();
        contentsOut.annotations.size = 0;
        int maxAnnotationBytes = aContents.annotations.byteCount
                + bContents.annotations.byteCount;
        annotationWriter = dexWriter.appendSection(maxAnnotationBytes, "annotation");

        contentsOut.encodedArrays.off = dexWriter.getLength();
        contentsOut.encodedArrays.size = 0;
        int maxEncodedArrayBytes = aContents.encodedArrays.byteCount
                + bContents.encodedArrays.byteCount;
        encodedArrayWriter = dexWriter.appendSection(
                maxEncodedArrayBytes * 2, "encoded array");

        contentsOut.annotationsDirectories.off = dexWriter.getLength();
        contentsOut.annotationsDirectories.size = 0;
        int maxAnnotationsDirectoryBytes = aContents.annotationsDirectories.byteCount
                + bContents.annotationsDirectories.byteCount;
        annotationsDirectoryWriter = dexWriter.appendSection(
                maxAnnotationsDirectoryBytes, "annotations");

        dexWriter.noMoreSections();
        contentsOut.dataSize = dexWriter.getLength() - contentsOut.dataOff;
    }

    public DexBuffer merge() throws IOException {
        long start = System.nanoTime();

        mergeStringIds();
        mergeTypeIds();
        mergeProtoIds();
        mergeFieldIds();
        mergeMethodIds();
        mergeClassDefs();

        // write the header
        contentsOut.header.off = 0;
        contentsOut.header.size = 1;
        contentsOut.fileSize = dexWriter.getLength();
        contentsOut.writeHeader(headerWriter);
        contentsOut.writeMap(mapListWriter);

        // close (and flush) the result, then reopen to generate and write the hashes
        new DexHasher().writeHashes(dexWriter);

        long elapsed = System.nanoTime() - start;
        logger.info(String.format("Merged dex A (%d defs/%.1fKiB) with dex B "
                + "(%d defs/%.1fKiB). Result is %d defs/%.1fKiB. Took %.1fs",
                dexA.getTableOfContents().classDefs.size,
                dexA.getLength() / 1024f,
                dexB.getTableOfContents().classDefs.size,
                dexB.getLength() / 1024f,
                contentsOut.classDefs.size,
                dexWriter.getLength() / 1024f,
                elapsed / 1000000000f));

        return dexWriter;
    }

    /**
     * Reads an IDs section of two dex files and writes an IDs section of a
     * merged dex file. Populates maps from old to new indices in the process.
     */
    abstract class IdMerger<T extends Comparable<T>> {
        public final void merge() {
            TableOfContents.Section aSection = getSection(dexA.getTableOfContents());
            TableOfContents.Section bSection = getSection(dexB.getTableOfContents());
            getSection(contentsOut).off = idsDefsWriter.getPosition();

            int aIndex = 0;
            int bIndex = 0;
            int outCount = 0;
            T a = null;
            T b = null;

            while (true) {
                if (a == null && aIndex < aSection.size) {
                    a = read(dexA, aIndexMap, aIndex);
                }
                if (b == null && bIndex < bSection.size) {
                    b = read(dexB, bIndexMap, bIndex);
                }

                // Write the smaller of a and b. If they're equal, write only once
                boolean advanceA;
                boolean advanceB;
                if (a != null && b != null) {
                    int compare = a.compareTo(b);
                    advanceA = compare <= 0;
                    advanceB = compare >= 0;
                } else {
                    advanceA = (a != null);
                    advanceB = (b != null);
                }

                T toWrite = null;
                if (advanceA) {
                    toWrite = a;
                    updateIndex(aIndexMap, aIndex++, outCount);
                    a = null;
                }
                if (advanceB) {
                    toWrite = b;
                    updateIndex(bIndexMap, bIndex++, outCount);
                    b = null;
                }
                if (toWrite == null) {
                    break; // advanceA == false && advanceB == false
                }
                write(toWrite);
                outCount++;
            }

            getSection(contentsOut).size = outCount;
        }

        abstract TableOfContents.Section getSection(TableOfContents tableOfContents);
        abstract T read(DexBuffer dexBuffer, IndexMap indexMap, int index);
        abstract void updateIndex(IndexMap indexMap, int oldIndex, int newIndex);
        abstract void write(T value);
    }

    private void mergeStringIds() {
        new IdMerger<String>() {
            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {
                return tableOfContents.stringIds;
            }

            @Override String read(DexBuffer dexBuffer, IndexMap indexMap, int index) {
                return dexBuffer.strings().get(index);
            }

            @Override void updateIndex(IndexMap indexMap, int oldIndex, int newIndex) {
                indexMap.stringIds[oldIndex] = newIndex;
            }

            @Override void write(String value) {
                contentsOut.stringDatas.size++;
                idsDefsWriter.writeInt(stringDataWriter.getPosition());
                stringDataWriter.writeStringData(value);
            }
        }.merge();
    }

    private void mergeTypeIds() {
        new IdMerger<Integer>() {
            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {
                return tableOfContents.typeIds;
            }

            @Override Integer read(DexBuffer dexBuffer, IndexMap indexMap, int index) {
                Integer stringIndex = dexBuffer.typeIds().get(index);
                return indexMap.adjustString(stringIndex);
            }

            @Override void updateIndex(IndexMap indexMap, int oldIndex, int newIndex) {
                indexMap.typeIds[oldIndex] = (short) newIndex;
            }

            @Override void write(Integer value) {
                idsDefsWriter.writeInt(value);
            }
        }.merge();
    }

    private void mergeProtoIds() {
        new IdMerger<ProtoId>() {
            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {
                return tableOfContents.protoIds;
            }

            @Override ProtoId read(DexBuffer dexBuffer, IndexMap indexMap, int index) {
                return indexMap.adjust(dexBuffer.protoIds().get(index));
            }

            @Override void updateIndex(IndexMap indexMap, int oldIndex, int newIndex) {
                indexMap.protoIds[oldIndex] = (short) newIndex;
            }

            @Override void write(ProtoId value) {
                int typeListPosition = writeTypeList(value.getParameters());
                value.writeTo(idsDefsWriter, typeListPosition);
            }
        }.merge();
    }

    private void mergeFieldIds() {
        new IdMerger<FieldId>() {
            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {
                return tableOfContents.fieldIds;
            }

            @Override FieldId read(DexBuffer dexBuffer, IndexMap indexMap, int index) {
                return indexMap.adjust(dexBuffer.fieldIds().get(index));
            }

            @Override void updateIndex(IndexMap indexMap, int oldIndex, int newIndex) {
                indexMap.fieldIds[oldIndex] = (short) newIndex;
            }

            @Override void write(FieldId value) {
                value.writeTo(idsDefsWriter);
            }
        }.merge();
    }

    private void mergeMethodIds() {
        new IdMerger<MethodId>() {
            @Override TableOfContents.Section getSection(TableOfContents tableOfContents) {
                return tableOfContents.methodIds;
            }

            @Override MethodId read(DexBuffer dexBuffer, IndexMap indexMap, int index) {
                return indexMap.adjust(dexBuffer.methodIds().get(index));
            }

            @Override void updateIndex(IndexMap indexMap, int oldIndex, int newIndex) {
                indexMap.methodIds[oldIndex] = (short) newIndex;
            }

            @Override void write(MethodId methodId) {
                methodId.writeTo(idsDefsWriter);
            }
        }.merge();
    }

    private void mergeClassDefs() {
        SortableType[] types = getSortedTypes();
        contentsOut.classDefs.off = idsDefsWriter.getPosition();
        contentsOut.classDefs.size = types.length;

        for (SortableType type : types) {
            DexBuffer in = type.getBuffer();
            IndexMap indexMap = (in == dexA) ? aIndexMap : bIndexMap;
            transformClassDef(in, type.getClassDef(), indexMap);
        }
    }

    /**
     * Returns the union of classes from both files, sorted in order such that
     * a class is always preceded by its supertype and implemented interfaces.
     */
    private SortableType[] getSortedTypes() {
        // size is pessimistic; doesn't include arrays
        SortableType[] sortableTypes = new SortableType[contentsOut.typeIds.size];
        readSortableTypes(sortableTypes, dexA, aIndexMap);
        readSortableTypes(sortableTypes, dexB, bIndexMap);

        /*
         * Populate the depths of each sortable type. This makes D iterations
         * through all N types, where 'D' is the depth of the deepest type. For
         * example, the deepest class in libcore is Xalan's KeyIterator, which
         * is 11 types deep.
         */
        while (true) {
            boolean allDone = true;
            for (SortableType sortableType : sortableTypes) {
                if (sortableType != null && !sortableType.isDepthAssigned()) {
                    allDone &= sortableType.tryAssignDepth(sortableTypes);
                }
            }
            if (allDone) {
                break;
            }
        }

        // Now that all types have depth information, the result can be sorted
        Arrays.sort(sortableTypes, SortableType.NULLS_LAST_ORDER);

        // Strip nulls from the end
        int firstNull = Arrays.asList(sortableTypes).indexOf(null);
        return firstNull != -1
                ? Arrays.copyOfRange(sortableTypes, 0, firstNull)
                : sortableTypes;
    }

    /**
     * Reads just enough data on each class so that we can sort it and then find
     * it later.
     */
    private void readSortableTypes(SortableType[] sortableTypes, DexBuffer buffer,
            IndexMap indexMap) {
        for (ClassDef classDef : buffer.classDefs()) {
            SortableType sortableType = indexMap.adjust(new SortableType(buffer, classDef));
            int t = sortableType.getTypeIndex();
            if (sortableTypes[t] == null) {
                sortableTypes[t] = sortableType;
            }
        }
    }

    /**
     * Reads a class_def_item beginning at {@code in} and writes the index and
     * data.
     */
    private void transformClassDef(DexBuffer in, ClassDef classDef, IndexMap indexMap) {
        idsDefsWriter.assertFourByteAligned();
        idsDefsWriter.writeInt(classDef.getTypeIndex());
        idsDefsWriter.writeInt(classDef.getAccessFlags());
        idsDefsWriter.writeInt(classDef.getSupertypeIndex());

        short[] interfaces = classDef.getInterfaces();
        int typeListPosition = writeTypeList(interfaces);
        idsDefsWriter.writeInt(typeListPosition);

        int sourceFileIndex = indexMap.adjustString(
                classDef.getSourceFileIndex()); // source file idx
        idsDefsWriter.writeInt(sourceFileIndex);

        int annotationsOff = classDef.getAnnotationsOffset();
        if (annotationsOff == 0) {
            idsDefsWriter.writeInt(0);
        } else {
            DexBuffer.Section annotationsIn = in.open(annotationsOff);
            annotationsDirectoryWriter.alignToFourBytes();
            idsDefsWriter.writeInt(annotationsDirectoryWriter.getPosition());
            transformAnnotations(annotationsIn, indexMap);
        }

        int classDataOff = classDef.getClassDataOffset();
        if (classDataOff == 0) {
            idsDefsWriter.writeInt(0);
        } else {
            idsDefsWriter.writeInt(classDataWriter.getPosition());
            ClassData classData = in.readClassData(classDef);
            transformClassData(in, classData, indexMap);
        }

        int staticValuesOff = classDef.getStaticValuesOffset();
        if (staticValuesOff == 0) {
            idsDefsWriter.writeInt(0);
        } else {
            DexBuffer.Section staticValuesIn = in.open(staticValuesOff);
            idsDefsWriter.writeInt(encodedArrayWriter.getPosition());
            transformStaticValues(staticValuesIn, indexMap);
        }
    }

    private int writeTypeList(short[] interfaces) {
        if (interfaces.length == 0) {
            return 0;
        }
        contentsOut.typeLists.size++;
        typeListWriter.alignToFourBytes();
        int cursor = typeListWriter.getPosition();
        typeListWriter.writeInt(interfaces.length);
        typeListWriter.write(interfaces);
        return cursor;
    }

    private void transformAnnotations(DexBuffer.Section in, IndexMap indexMap) {
        contentsOut.annotationsDirectories.size++;

        // TODO: retain annotations
        annotationsDirectoryWriter.assertFourByteAligned();
        in.readInt(); // class annotations off
        in.readInt(); // fields size
        in.readInt(); // annotated methods size
        in.readInt(); // annotated parameters size

        annotationsDirectoryWriter.writeInt(0);
        annotationsDirectoryWriter.writeInt(0);
        annotationsDirectoryWriter.writeInt(0);
        annotationsDirectoryWriter.writeInt(0);
    }

    private void transformClassData(DexBuffer in, ClassData classData, IndexMap indexMap) {
        contentsOut.classDatas.size++;

        ClassData.Field[] staticFields = classData.getStaticFields();
        ClassData.Field[] instanceFields = classData.getInstanceFields();
        ClassData.Method[] directMethods = classData.getDirectMethods();
        ClassData.Method[] virtualMethods = classData.getVirtualMethods();

        classDataWriter.writeUleb128(staticFields.length);
        classDataWriter.writeUleb128(instanceFields.length);
        classDataWriter.writeUleb128(directMethods.length);
        classDataWriter.writeUleb128(virtualMethods.length);

        transformFields(indexMap, staticFields);
        transformFields(indexMap, instanceFields);
        transformMethods(in, indexMap, directMethods);
        transformMethods(in, indexMap, virtualMethods);
    }

    private void transformFields(IndexMap indexMap, ClassData.Field[] fields) {
        int lastOutFieldIndex = 0;
        for (ClassData.Field field : fields) {
            int outFieldIndex = indexMap.adjustField(field.getFieldIndex());
            classDataWriter.writeUleb128(outFieldIndex - lastOutFieldIndex);
            lastOutFieldIndex = outFieldIndex;
            classDataWriter.writeUleb128(field.getAccessFlags());
        }
    }

    private void transformMethods(DexBuffer in, IndexMap indexMap, ClassData.Method[] methods) {
        int lastOutMethodIndex = 0;
        for (ClassData.Method method : methods) {
            int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());
            classDataWriter.writeUleb128(outMethodIndex - lastOutMethodIndex);
            lastOutMethodIndex = outMethodIndex;

            classDataWriter.writeUleb128(method.getAccessFlags());

            if (method.getCodeOffset() == 0) {
                classDataWriter.writeUleb128(0);
            } else {
                codeWriter.alignToFourBytes();
                classDataWriter.writeUleb128(codeWriter.getPosition());
                transformCode(in, in.readCode(method), indexMap);
            }
        }
    }

    private void transformCode(DexBuffer in, Code code, IndexMap indexMap) {
        contentsOut.codes.size++;
        codeWriter.assertFourByteAligned();

        codeWriter.writeShort(code.getRegistersSize());
        codeWriter.writeShort(code.getInsSize());
        codeWriter.writeShort(code.getOutsSize());

        Code.Try[] tries = code.getTries();
        codeWriter.writeShort((short) tries.length);

        // TODO: retain debug info
        // code.getDebugInfoOffset();
        codeWriter.writeInt(0);

        short[] instructions = code.getInstructions();
        InstructionTransformer transformer = (in == dexA)
                ? aInstructionTransformer
                : bInstructionTransformer;
        short[] newInstructions = transformer.transform(instructions);
        codeWriter.writeInt(newInstructions.length);
        codeWriter.write(newInstructions);

        if (tries.length > 0) {
            if (newInstructions.length % 2 == 1) {
                codeWriter.writeShort((short) 0); // padding
            }
            for (Code.Try tryItem : tries) {
                codeWriter.writeInt(tryItem.getStartAddress());
                codeWriter.writeShort(tryItem.getInstructionCount());
                codeWriter.writeShort(tryItem.getHandlerOffset());
            }
            Code.CatchHandler[] catchHandlers = code.getCatchHandlers();
            codeWriter.writeUleb128(catchHandlers.length);
            for (Code.CatchHandler catchHandler : catchHandlers) {
                transformEncodedCatchHandler(catchHandler, indexMap);
            }
        }
    }

    private void transformEncodedCatchHandler(Code.CatchHandler catchHandler, IndexMap indexMap) {
        int catchAllAddress = catchHandler.getCatchAllAddress();
        int[] typeIndexes = catchHandler.getTypeIndexes();
        int[] addresses = catchHandler.getAddresses();

        if (catchAllAddress != -1) {
            codeWriter.writeSleb128(-typeIndexes.length);
        } else {
            codeWriter.writeSleb128(typeIndexes.length);
        }

        for (int i = 0; i < typeIndexes.length; i++) {
            codeWriter.writeUleb128(indexMap.adjustType(typeIndexes[i]));
            codeWriter.writeUleb128(addresses[i]);
        }

        if (catchAllAddress != -1) {
            codeWriter.writeUleb128(catchAllAddress);
        }
    }

    private void transformStaticValues(DexBuffer.Section in, IndexMap indexMap) {
        contentsOut.encodedArrays.size++;
        new EncodedValueTransformer(indexMap, in, encodedArrayWriter).transformArray();
    }

    public static void main(String[] args) throws IOException {
        if (args.length != 3) {
            printUsage();
            return;
        }

        DexBuffer dexA = new DexBuffer();
        dexA.loadFrom(new File(args[1]));
        DexBuffer dexB = new DexBuffer();
        dexB.loadFrom(new File(args[2]));

        DexBuffer merged = new DexMerger(dexA, dexB).merge();
        merged.writeTo(new File(args[0]));
    }

    private static void printUsage() {
        System.out.println("Usage: DexMerger <out.dex> <a.dex> <b.dex>");
        System.out.println();
        System.out.println("If both a and b define the same classes, a's copy will be used.");
    }
}
