/*
 * Copyright (C) 2008 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.dex.file;

import com.android.dx.util.AnnotatedOutput;
import com.android.dx.util.Hex;

import java.util.ArrayList;

/**
 * Class that represents a map item.
 */
public final class MapItem extends OffsettedItem {
    /** file alignment of this class, in bytes */
    private static final int ALIGNMENT = 4;

    /** write size of this class, in bytes: three {@code uint}s */
    private static final int WRITE_SIZE = (4 * 3);

    /** {@code non-null;} item type this instance covers */
    private final ItemType type;

    /** {@code non-null;} section this instance covers */
    private final Section section;

    /**
     * {@code null-ok;} first item covered or {@code null} if this is
     * a self-reference
     */
    private final Item firstItem;

    /**
     * {@code null-ok;} last item covered or {@code null} if this is
     * a self-reference
     */
    private final Item lastItem;

    /**
     * {@code > 0;} count of items covered; {@code 1} if this
     * is a self-reference
     */
    private final int itemCount;

    /**
     * Constructs a list item with instances of this class representing
     * the contents of the given array of sections, adding it to the
     * given map section.
     *
     * @param sections {@code non-null;} the sections
     * @param mapSection {@code non-null;} the section that the resulting map
     * should be added to; it should be empty on entry to this method
     */
    public static void addMap(Section[] sections,
            MixedItemSection mapSection) {
        if (sections == null) {
            throw new NullPointerException("sections == null");
        }

        if (mapSection.items().size() != 0) {
            throw new IllegalArgumentException(
                    "mapSection.items().size() != 0");
        }

        ArrayList<MapItem> items = new ArrayList<MapItem>(50);

        for (Section section : sections) {
            ItemType currentType = null;
            Item firstItem = null;
            Item lastItem = null;
            int count = 0;

            for (Item item : section.items()) {
                ItemType type = item.itemType();
                if (type != currentType) {
                    if (count != 0) {
                        items.add(new MapItem(currentType, section,
                                        firstItem, lastItem, count));
                    }
                    currentType = type;
                    firstItem = item;
                    count = 0;
                }
                lastItem = item;
                count++;
            }

            if (count != 0) {
                // Add a MapItem for the final items in the section.
                items.add(new MapItem(currentType, section,
                                firstItem, lastItem, count));
            } else if (section == mapSection) {
                // Add a MapItem for the self-referential section.
                items.add(new MapItem(mapSection));
            }
        }

        mapSection.add(
                new UniformListItem<MapItem>(ItemType.TYPE_MAP_LIST, items));
    }

    /**
     * Constructs an instance.
     *
     * @param type {@code non-null;} item type this instance covers
     * @param section {@code non-null;} section this instance covers
     * @param firstItem {@code non-null;} first item covered
     * @param lastItem {@code non-null;} last item covered
     * @param itemCount {@code > 0;} count of items covered
     */
    private MapItem(ItemType type, Section section, Item firstItem,
            Item lastItem, int itemCount) {
        super(ALIGNMENT, WRITE_SIZE);

        if (type == null) {
            throw new NullPointerException("type == null");
        }

        if (section == null) {
            throw new NullPointerException("section == null");
        }

        if (firstItem == null) {
            throw new NullPointerException("firstItem == null");
        }

        if (lastItem == null) {
            throw new NullPointerException("lastItem == null");
        }

        if (itemCount <= 0) {
            throw new IllegalArgumentException("itemCount <= 0");
        }

        this.type = type;
        this.section = section;
        this.firstItem = firstItem;
        this.lastItem = lastItem;
        this.itemCount = itemCount;
    }

    /**
     * Constructs a self-referential instance. This instance is meant to
     * represent the section containing the {@code map_list}.
     *
     * @param section {@code non-null;} section this instance covers
     */
    private MapItem(Section section) {
        super(ALIGNMENT, WRITE_SIZE);

        if (section == null) {
            throw new NullPointerException("section == null");
        }

        this.type = ItemType.TYPE_MAP_LIST;
        this.section = section;
        this.firstItem = null;
        this.lastItem = null;
        this.itemCount = 1;
    }

    /** {@inheritDoc} */
    @Override
    public ItemType itemType() {
        return ItemType.TYPE_MAP_ITEM;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer(100);

        sb.append(getClass().getName());
        sb.append('{');
        sb.append(section.toString());
        sb.append(' ');
        sb.append(type.toHuman());
        sb.append('}');

        return sb.toString();
    }

    /** {@inheritDoc} */
    @Override
    public void addContents(DexFile file) {
        // We have nothing to add.
    }

    /** {@inheritDoc} */
    @Override
    public final String toHuman() {
        return toString();
    }

    /** {@inheritDoc} */
    @Override
    protected void writeTo0(DexFile file, AnnotatedOutput out) {
        int value = type.getMapValue();
        int offset;

        if (firstItem == null) {
            offset = section.getFileOffset();
        } else {
            offset = section.getAbsoluteItemOffset(firstItem);
        }

        if (out.annotates()) {
            out.annotate(0, offsetString() + ' ' + type.getTypeName() +
                    " map");
            out.annotate(2, "  type:   " + Hex.u2(value) + " // " +
                    type.toString());
            out.annotate(2, "  unused: 0");
            out.annotate(4, "  size:   " + Hex.u4(itemCount));
            out.annotate(4, "  offset: " + Hex.u4(offset));
        }

        out.writeShort(value);
        out.writeShort(0); // unused
        out.writeInt(itemCount);
        out.writeInt(offset);
    }
}
