/*
 * 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.dex;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * The file header and map.
 */
public final class TableOfContents {

    /*
     * TODO: factor out ID constants.
     */

    public final Section header = new Section(0x0000);
    public final Section stringIds = new Section(0x0001);
    public final Section typeIds = new Section(0x0002);
    public final Section protoIds = new Section(0x0003);
    public final Section fieldIds = new Section(0x0004);
    public final Section methodIds = new Section(0x0005);
    public final Section classDefs = new Section(0x0006);
    public final Section mapList = new Section(0x1000);
    public final Section typeLists = new Section(0x1001);
    public final Section annotationSetRefLists = new Section(0x1002);
    public final Section annotationSets = new Section(0x1003);
    public final Section classDatas = new Section(0x2000);
    public final Section codes = new Section(0x2001);
    public final Section stringDatas = new Section(0x2002);
    public final Section debugInfos = new Section(0x2003);
    public final Section annotations = new Section(0x2004);
    public final Section encodedArrays = new Section(0x2005);
    public final Section annotationsDirectories = new Section(0x2006);
    public final Section[] sections = {
            header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList,
            typeLists, annotationSetRefLists, annotationSets, classDatas, codes, stringDatas,
            debugInfos, annotations, encodedArrays, annotationsDirectories
    };

    public int checksum;
    public byte[] signature;
    public int fileSize;
    public int linkSize;
    public int linkOff;
    public int dataSize;
    public int dataOff;

    public TableOfContents() {
        signature = new byte[20];
    }

    public void readFrom(Dex dex) throws IOException {
        readHeader(dex.open(0));
        readMap(dex.open(mapList.off));
        computeSizesFromOffsets();
    }

    private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
        byte[] magic = headerIn.readByteArray(8);
        int apiTarget = DexFormat.magicToApi(magic);

        if (apiTarget != DexFormat.API_NO_EXTENDED_OPCODES) {
            throw new DexException("Unexpected magic: " + Arrays.toString(magic));
        }

        checksum = headerIn.readInt();
        signature = headerIn.readByteArray(20);
        fileSize = headerIn.readInt();
        int headerSize = headerIn.readInt();
        if (headerSize != SizeOf.HEADER_ITEM) {
            throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize));
        }
        int endianTag = headerIn.readInt();
        if (endianTag != DexFormat.ENDIAN_TAG) {
            throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag));
        }
        linkSize = headerIn.readInt();
        linkOff = headerIn.readInt();
        mapList.off = headerIn.readInt();
        if (mapList.off == 0) {
            throw new DexException("Cannot merge dex files that do not contain a map");
        }
        stringIds.size = headerIn.readInt();
        stringIds.off = headerIn.readInt();
        typeIds.size = headerIn.readInt();
        typeIds.off = headerIn.readInt();
        protoIds.size = headerIn.readInt();
        protoIds.off = headerIn.readInt();
        fieldIds.size = headerIn.readInt();
        fieldIds.off = headerIn.readInt();
        methodIds.size = headerIn.readInt();
        methodIds.off = headerIn.readInt();
        classDefs.size = headerIn.readInt();
        classDefs.off = headerIn.readInt();
        dataSize = headerIn.readInt();
        dataOff = headerIn.readInt();
    }

    private void readMap(Dex.Section in) throws IOException {
        int mapSize = in.readInt();
        Section previous = null;
        for (int i = 0; i < mapSize; i++) {
            short type = in.readShort();
            in.readShort(); // unused
            Section section = getSection(type);
            int size = in.readInt();
            int offset = in.readInt();

            if ((section.size != 0 && section.size != size)
                    || (section.off != -1 && section.off != offset)) {
                throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
            }

            section.size = size;
            section.off = offset;

            if (previous != null && previous.off > section.off) {
                throw new DexException("Map is unsorted at " + previous + ", " + section);
            }

            previous = section;
        }
        Arrays.sort(sections);
    }

    public void computeSizesFromOffsets() {
        int end = dataOff + dataSize;
        for (int i = sections.length - 1; i >= 0; i--) {
            Section section = sections[i];
            if (section.off == -1) {
                continue;
            }
            if (section.off > end) {
                throw new DexException("Map is unsorted at " + section);
            }
            section.byteCount = end - section.off;
            end = section.off;
        }
    }

    private Section getSection(short type) {
        for (Section section : sections) {
            if (section.type == type) {
                return section;
            }
        }
        throw new IllegalArgumentException("No such map item: " + type);
    }

    public void writeHeader(Dex.Section out) throws IOException {
        out.write(DexFormat.apiToMagic(DexFormat.API_NO_EXTENDED_OPCODES).getBytes("UTF-8"));
        out.writeInt(checksum);
        out.write(signature);
        out.writeInt(fileSize);
        out.writeInt(SizeOf.HEADER_ITEM);
        out.writeInt(DexFormat.ENDIAN_TAG);
        out.writeInt(linkSize);
        out.writeInt(linkOff);
        out.writeInt(mapList.off);
        out.writeInt(stringIds.size);
        out.writeInt(stringIds.off);
        out.writeInt(typeIds.size);
        out.writeInt(typeIds.off);
        out.writeInt(protoIds.size);
        out.writeInt(protoIds.off);
        out.writeInt(fieldIds.size);
        out.writeInt(fieldIds.off);
        out.writeInt(methodIds.size);
        out.writeInt(methodIds.off);
        out.writeInt(classDefs.size);
        out.writeInt(classDefs.off);
        out.writeInt(dataSize);
        out.writeInt(dataOff);
    }

    public void writeMap(Dex.Section out) throws IOException {
        int count = 0;
        for (Section section : sections) {
            if (section.exists()) {
                count++;
            }
        }

        out.writeInt(count);
        for (Section section : sections) {
            if (section.exists()) {
                out.writeShort(section.type);
                out.writeShort((short) 0);
                out.writeInt(section.size);
                out.writeInt(section.off);
            }
        }
    }

    public static class Section implements Comparable<Section> {
        public final short type;
        public int size = 0;
        public int off = -1;
        public int byteCount = 0;

        public Section(int type) {
            this.type = (short) type;
        }

        public boolean exists() {
            return size > 0;
        }

        public int compareTo(Section section) {
            if (off != section.off) {
                return off < section.off ? -1 : 1;
            }
            return 0;
        }

        @Override public String toString() {
            return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size);
        }
    }
}
