/*
 * 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);
}
