/*
 * Copyright (C) 2007 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.ExceptionWithContext;

/**
 * An item in a Dalvik file which is referenced by absolute offset.
 */
public abstract class OffsettedItem extends Item
        implements Comparable<OffsettedItem> {
    /** {@code > 0;} alignment requirement */
    private final int alignment;

    /** {@code >= -1;} the size of this instance when written, in bytes, or
     * {@code -1} if not yet known */
    private int writeSize;

    /**
     * {@code null-ok;} section the item was added to, or {@code null} if
     * not yet added
     */
    private Section addedTo;

    /**
     * {@code >= -1;} assigned offset of the item from the start of its section,
     * or {@code -1} if not yet assigned
     */
    private int offset;

    /**
     * Gets the absolute offset of the given item, returning {@code 0}
     * if handed {@code null}.
     *
     * @param item {@code null-ok;} the item in question
     * @return {@code >= 0;} the item's absolute offset, or {@code 0}
     * if {@code item == null}
     */
    public static int getAbsoluteOffsetOr0(OffsettedItem item) {
        if (item == null) {
            return 0;
        }

        return item.getAbsoluteOffset();
    }

    /**
     * Constructs an instance. The offset is initially unassigned.
     *
     * @param alignment {@code > 0;} output alignment requirement; must be a
     * power of 2
     * @param writeSize {@code >= -1;} the size of this instance when written,
     * in bytes, or {@code -1} if not immediately known
     */
    public OffsettedItem(int alignment, int writeSize) {
        Section.validateAlignment(alignment);

        if (writeSize < -1) {
            throw new IllegalArgumentException("writeSize < -1");
        }

        this.alignment = alignment;
        this.writeSize = writeSize;
        this.addedTo = null;
        this.offset = -1;
    }

    /**
     * {@inheritDoc}
     *
     * Comparisons for this class are defined to be type-major (if the
     * types don't match then the objects are not equal), with
     * {@link #compareTo0} deciding same-type comparisons.
     */
    @Override
    public final boolean equals(Object other) {
        if (this == other) {
            return true;
        }

        OffsettedItem otherItem = (OffsettedItem) other;
        ItemType thisType = itemType();
        ItemType otherType = otherItem.itemType();

        if (thisType != otherType) {
            return false;
        }

        return (compareTo0(otherItem) == 0);
    }

    /**
     * {@inheritDoc}
     *
     * Comparisons for this class are defined to be class-major (if the
     * classes don't match then the objects are not equal), with
     * {@link #compareTo0} deciding same-class comparisons.
     */
    public final int compareTo(OffsettedItem other) {
        if (this == other) {
            return 0;
        }

        ItemType thisType = itemType();
        ItemType otherType = other.itemType();

        if (thisType != otherType) {
            return thisType.compareTo(otherType);
        }

        return compareTo0(other);
    }

    /**
     * Sets the write size of this item. This may only be called once
     * per instance, and only if the size was unknown upon instance
     * creation.
     *
     * @param writeSize {@code > 0;} the write size, in bytes
     */
    public final void setWriteSize(int writeSize) {
        if (writeSize < 0) {
            throw new IllegalArgumentException("writeSize < 0");
        }

        if (this.writeSize >= 0) {
            throw new UnsupportedOperationException("writeSize already set");
        }

        this.writeSize = writeSize;
    }

    /** {@inheritDoc}
     *
     * @throws UnsupportedOperationException thrown if the write size
     * is not yet known
     */
    @Override
    public final int writeSize() {
        if (writeSize < 0) {
            throw new UnsupportedOperationException("writeSize is unknown");
        }

        return writeSize;
    }

    /** {@inheritDoc} */
    @Override
    public final void writeTo(DexFile file, AnnotatedOutput out) {
        out.alignTo(alignment);

        try {
            if (writeSize < 0) {
                throw new UnsupportedOperationException(
                        "writeSize is unknown");
            }
            out.assertCursor(getAbsoluteOffset());
        } catch (RuntimeException ex) {
            throw ExceptionWithContext.withContext(ex,
                    "...while writing " + this);
        }

        writeTo0(file, out);
    }

    /**
     * Gets the relative item offset. The offset is from the start of
     * the section which the instance was written to.
     *
     * @return {@code >= 0;} the offset
     * @throws RuntimeException thrown if the offset is not yet known
     */
    public final int getRelativeOffset() {
        if (offset < 0) {
            throw new RuntimeException("offset not yet known");
        }

        return offset;
    }

    /**
     * Gets the absolute item offset. The offset is from the start of
     * the file which the instance was written to.
     *
     * @return {@code >= 0;} the offset
     * @throws RuntimeException thrown if the offset is not yet known
     */
    public final int getAbsoluteOffset() {
        if (offset < 0) {
            throw new RuntimeException("offset not yet known");
        }

        return addedTo.getAbsoluteOffset(offset);
    }

    /**
     * Indicates that this item has been added to the given section at
     * the given offset. It is only valid to call this method once per
     * instance.
     *
     * @param addedTo {@code non-null;} the section this instance has
     * been added to
     * @param offset {@code >= 0;} the desired offset from the start of the
     * section where this instance was placed
     * @return {@code >= 0;} the offset that this instance should be placed at
     * in order to meet its alignment constraint
     */
    public final int place(Section addedTo, int offset) {
        if (addedTo == null) {
            throw new NullPointerException("addedTo == null");
        }

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

        if (this.addedTo != null) {
            throw new RuntimeException("already written");
        }

        int mask = alignment - 1;
        offset = (offset + mask) & ~mask;

        this.addedTo = addedTo;
        this.offset = offset;

        place0(addedTo, offset);

        return offset;
    }

    /**
     * Gets the alignment requirement of this instance. An instance should
     * only be written when so aligned.
     *
     * @return {@code > 0;} the alignment requirement; must be a power of 2
     */
    public final int getAlignment() {
        return alignment;
    }

    /**
     * Gets the absolute offset of this item as a string, suitable for
     * including in annotations.
     *
     * @return {@code non-null;} the offset string
     */
    public final String offsetString() {
        return '[' + Integer.toHexString(getAbsoluteOffset()) + ']';
    }

    /**
     * Gets a short human-readable string representing this instance.
     *
     * @return {@code non-null;} the human form
     */
    public abstract String toHuman();

    /**
     * Compares this instance to another which is guaranteed to be of
     * the same class. The default implementation of this method is to
     * throw an exception (unsupported operation). If a particular
     * class needs to actually sort, then it should override this
     * method.
     *
     * @param other {@code non-null;} instance to compare to
     * @return {@code -1}, {@code 0}, or {@code 1}, depending
     * on the sort order of this instance and the other
     */
    protected int compareTo0(OffsettedItem other) {
        throw new UnsupportedOperationException("unsupported");
    }

    /**
     * Does additional work required when placing an instance. The
     * default implementation of this method is a no-op. If a
     * particular class needs to do something special, then it should
     * override this method. In particular, if this instance did not
     * know its write size up-front, then this method is responsible
     * for setting it.
     *
     * @param addedTo {@code non-null;} the section this instance has been added to
     * @param offset {@code >= 0;} the offset from the start of the
     * section where this instance was placed
     */
    protected void place0(Section addedTo, int offset) {
        // This space intentionally left blank.
    }

    /**
     * Performs the actual write of the contents of this instance to
     * the given data section. This is called by {@link #writeTo},
     * which will have taken care of ensuring alignment.
     *
     * @param file {@code non-null;} the file to use for reference
     * @param out {@code non-null;} where to write to
     */
    protected abstract void writeTo0(DexFile file, AnnotatedOutput out);
}
