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

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

/**
 * Implementation of {@link AnnotatedOutput} which stores the written data
 * into a {@code byte[]}.
 *
 * <p><b>Note:</b> As per the {@link Output} interface, multi-byte
 * writes all use little-endian order.</p>
 */
public final class ByteArrayAnnotatedOutput
        implements AnnotatedOutput, ByteOutput {
    /** default size for stretchy instances */
    private static final int DEFAULT_SIZE = 1000;

    /**
     * whether the instance is stretchy, that is, whether its array
     * may be resized to increase capacity
     */
    private final boolean stretchy;

    /** {@code non-null;} the data itself */
    private byte[] data;

    /** {@code >= 0;} current output cursor */
    private int cursor;

    /** whether annotations are to be verbose */
    private boolean verbose;

    /**
     * {@code null-ok;} list of annotations, or {@code null} if this instance
     * isn't keeping them
     */
    private ArrayList<Annotation> annotations;

    /** {@code >= 40 (if used);} the desired maximum annotation width */
    private int annotationWidth;

    /**
     * {@code >= 8 (if used);} the number of bytes of hex output to use
     * in annotations
     */
    private int hexCols;

    /**
     * Constructs an instance with a fixed maximum size. Note that the
     * given array is the only one that will be used to store data. In
     * particular, no reallocation will occur in order to expand the
     * capacity of the resulting instance. Also, the constructed
     * instance does not keep annotations by default.
     *
     * @param data {@code non-null;} data array to use for output
     */
    public ByteArrayAnnotatedOutput(byte[] data) {
        this(data, false);
    }

    /**
     * Constructs a "stretchy" instance. The underlying array may be
     * reallocated. The constructed instance does not keep annotations
     * by default.
     */
    public ByteArrayAnnotatedOutput() {
        this(DEFAULT_SIZE);
    }

    /**
     * Constructs a "stretchy" instance with initial size {@code size}. The
     * underlying array may be reallocated. The constructed instance does not
     * keep annotations by default.
     */
    public ByteArrayAnnotatedOutput(int size) {
        this(new byte[size], true);
    }

    /**
     * Internal constructor.
     *
     * @param data {@code non-null;} data array to use for output
     * @param stretchy whether the instance is to be stretchy
     */
    private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) {
        if (data == null) {
            throw new NullPointerException("data == null");
        }

        this.stretchy = stretchy;
        this.data = data;
        this.cursor = 0;
        this.verbose = false;
        this.annotations = null;
        this.annotationWidth = 0;
        this.hexCols = 0;
    }

    /**
     * Gets the underlying {@code byte[]} of this instance, which
     * may be larger than the number of bytes written
     *
     * @see #toByteArray
     *
     * @return {@code non-null;} the {@code byte[]}
     */
    public byte[] getArray() {
        return data;
    }

    /**
     * Constructs and returns a new {@code byte[]} that contains
     * the written contents exactly (that is, with no extra unwritten
     * bytes at the end).
     *
     * @see #getArray
     *
     * @return {@code non-null;} an appropriately-constructed array
     */
    public byte[] toByteArray() {
        byte[] result = new byte[cursor];
        System.arraycopy(data, 0, result, 0, cursor);
        return result;
    }

    /** {@inheritDoc} */
    public int getCursor() {
        return cursor;
    }

    /** {@inheritDoc} */
    public void assertCursor(int expectedCursor) {
        if (cursor != expectedCursor) {
            throw new ExceptionWithContext("expected cursor " +
                    expectedCursor + "; actual value: " + cursor);
        }
    }

    /** {@inheritDoc} */
    public void writeByte(int value) {
        int writeAt = cursor;
        int end = writeAt + 1;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        data[writeAt] = (byte) value;
        cursor = end;
    }

    /** {@inheritDoc} */
    public void writeShort(int value) {
        int writeAt = cursor;
        int end = writeAt + 2;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        data[writeAt] = (byte) value;
        data[writeAt + 1] = (byte) (value >> 8);
        cursor = end;
    }

    /** {@inheritDoc} */
    public void writeInt(int value) {
        int writeAt = cursor;
        int end = writeAt + 4;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        data[writeAt] = (byte) value;
        data[writeAt + 1] = (byte) (value >> 8);
        data[writeAt + 2] = (byte) (value >> 16);
        data[writeAt + 3] = (byte) (value >> 24);
        cursor = end;
    }

    /** {@inheritDoc} */
    public void writeLong(long value) {
        int writeAt = cursor;
        int end = writeAt + 8;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        int half = (int) value;
        data[writeAt] = (byte) half;
        data[writeAt + 1] = (byte) (half >> 8);
        data[writeAt + 2] = (byte) (half >> 16);
        data[writeAt + 3] = (byte) (half >> 24);

        half = (int) (value >> 32);
        data[writeAt + 4] = (byte) half;
        data[writeAt + 5] = (byte) (half >> 8);
        data[writeAt + 6] = (byte) (half >> 16);
        data[writeAt + 7] = (byte) (half >> 24);

        cursor = end;
    }

    /** {@inheritDoc} */
    public int writeUleb128(int value) {
        if (stretchy) {
            ensureCapacity(cursor + 5); // pessimistic
        }
        int cursorBefore = cursor;
        Leb128Utils.writeUnsignedLeb128(this, value);
        return (cursor - cursorBefore);
    }

    /** {@inheritDoc} */
    public int writeSleb128(int value) {
        if (stretchy) {
            ensureCapacity(cursor + 5); // pessimistic
        }
        int cursorBefore = cursor;
        Leb128Utils.writeSignedLeb128(this, value);
        return (cursor - cursorBefore);
    }

    /** {@inheritDoc} */
    public void write(ByteArray bytes) {
        int blen = bytes.size();
        int writeAt = cursor;
        int end = writeAt + blen;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        bytes.getBytes(data, writeAt);
        cursor = end;
    }

    /** {@inheritDoc} */
    public void write(byte[] bytes, int offset, int length) {
        int writeAt = cursor;
        int end = writeAt + length;
        int bytesEnd = offset + length;

        // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0)
        if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) {
            throw new IndexOutOfBoundsException("bytes.length " +
                                                bytes.length + "; " +
                                                offset + "..!" + end);
        }

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        System.arraycopy(bytes, offset, data, writeAt, length);
        cursor = end;
    }

    /** {@inheritDoc} */
    public void write(byte[] bytes) {
        write(bytes, 0, bytes.length);
    }

    /** {@inheritDoc} */
    public void writeZeroes(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("count < 0");
        }

        int end = cursor + count;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        /*
         * There is no need to actually write zeroes, since the array is
         * already preinitialized with zeroes.
         */

        cursor = end;
    }

    /** {@inheritDoc} */
    public void alignTo(int alignment) {
        int mask = alignment - 1;

        if ((alignment < 0) || ((mask & alignment) != 0)) {
            throw new IllegalArgumentException("bogus alignment");
        }

        int end = (cursor + mask) & ~mask;

        if (stretchy) {
            ensureCapacity(end);
        } else if (end > data.length) {
            throwBounds();
            return;
        }

        /*
         * There is no need to actually write zeroes, since the array is
         * already preinitialized with zeroes.
         */

        cursor = end;
    }

    /** {@inheritDoc} */
    public boolean annotates() {
        return (annotations != null);
    }

    /** {@inheritDoc} */
    public boolean isVerbose() {
        return verbose;
    }

    /** {@inheritDoc} */
    public void annotate(String msg) {
        if (annotations == null) {
            return;
        }

        endAnnotation();
        annotations.add(new Annotation(cursor, msg));
    }

    /** {@inheritDoc} */
    public void annotate(int amt, String msg) {
        if (annotations == null) {
            return;
        }

        endAnnotation();

        int asz = annotations.size();
        int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd();
        int startAt;

        if (lastEnd <= cursor) {
            startAt = cursor;
        } else {
            startAt = lastEnd;
        }

        annotations.add(new Annotation(startAt, startAt + amt, msg));
    }

    /** {@inheritDoc} */
    public void endAnnotation() {
        if (annotations == null) {
            return;
        }

        int sz = annotations.size();

        if (sz != 0) {
            annotations.get(sz - 1).setEndIfUnset(cursor);
        }
    }

    /** {@inheritDoc} */
    public int getAnnotationWidth() {
        int leftWidth = 8 + (hexCols * 2) + (hexCols / 2);

        return annotationWidth - leftWidth;
    }

    /**
     * Indicates that this instance should keep annotations. This method may
     * be called only once per instance, and only before any data has been
     * written to the it.
     *
     * @param annotationWidth {@code >= 40;} the desired maximum annotation width
     * @param verbose whether or not to indicate verbose annotations
     */
    public void enableAnnotations(int annotationWidth, boolean verbose) {
        if ((annotations != null) || (cursor != 0)) {
            throw new RuntimeException("cannot enable annotations");
        }

        if (annotationWidth < 40) {
            throw new IllegalArgumentException("annotationWidth < 40");
        }

        int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1;
        if (hexCols < 6) {
            hexCols = 6;
        } else if (hexCols > 10) {
            hexCols = 10;
        }

        this.annotations = new ArrayList<Annotation>(1000);
        this.annotationWidth = annotationWidth;
        this.hexCols = hexCols;
        this.verbose = verbose;
    }

    /**
     * Finishes up annotation processing. This closes off any open
     * annotations and removes annotations that don't refer to written
     * data.
     */
    public void finishAnnotating() {
        // Close off the final annotation, if any.
        endAnnotation();

        // Remove annotations that refer to unwritten data.
        if (annotations != null) {
            int asz = annotations.size();
            while (asz > 0) {
                Annotation last = annotations.get(asz - 1);
                if (last.getStart() > cursor) {
                    annotations.remove(asz - 1);
                    asz--;
                } else if (last.getEnd() > cursor) {
                    last.setEnd(cursor);
                    break;
                } else {
                    break;
                }
            }
        }
    }

    /**
     * Writes the annotated content of this instance to the given writer.
     *
     * @param out {@code non-null;} where to write to
     */
    public void writeAnnotationsTo(Writer out) throws IOException {
        int width2 = getAnnotationWidth();
        int width1 = annotationWidth - width2 - 1;

        TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, "|");
        Writer left = twoc.getLeft();
        Writer right = twoc.getRight();
        int leftAt = 0; // left-hand byte output cursor
        int rightAt = 0; // right-hand annotation index
        int rightSz = annotations.size();

        while ((leftAt < cursor) && (rightAt < rightSz)) {
            Annotation a = annotations.get(rightAt);
            int start = a.getStart();
            int end;
            String text;

            if (leftAt < start) {
                // This is an area with no annotation.
                end = start;
                start = leftAt;
                text = "";
            } else {
                // This is an area with an annotation.
                end = a.getEnd();
                text = a.getText();
                rightAt++;
            }

            left.write(Hex.dump(data, start, end - start, start, hexCols, 6));
            right.write(text);
            twoc.flush();
            leftAt = end;
        }

        if (leftAt < cursor) {
            // There is unannotated output at the end.
            left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt,
                                hexCols, 6));
        }

        while (rightAt < rightSz) {
            // There are zero-byte annotations at the end.
            right.write(annotations.get(rightAt).getText());
            rightAt++;
        }

        twoc.flush();
    }

    /**
     * Throws the excpetion for when an attempt is made to write past the
     * end of the instance.
     */
    private static void throwBounds() {
        throw new IndexOutOfBoundsException("attempt to write past the end");
    }

    /**
     * Reallocates the underlying array if necessary. Calls to this method
     * should be guarded by a test of {@link #stretchy}.
     *
     * @param desiredSize {@code >= 0;} the desired minimum total size of the array
     */
    private void ensureCapacity(int desiredSize) {
        if (data.length < desiredSize) {
            byte[] newData = new byte[desiredSize * 2 + 1000];
            System.arraycopy(data, 0, newData, 0, cursor);
            data = newData;
        }
    }

    /**
     * Annotation on output.
     */
    private static class Annotation {
        /** {@code >= 0;} start of annotated range (inclusive) */
        private final int start;

        /**
         * {@code >= 0;} end of annotated range (exclusive);
         * {@code Integer.MAX_VALUE} if unclosed
         */
        private int end;

        /** {@code non-null;} annotation text */
        private final String text;

        /**
         * Constructs an instance.
         *
         * @param start {@code >= 0;} start of annotated range
         * @param end {@code >= start;} end of annotated range (exclusive) or
         * {@code Integer.MAX_VALUE} if unclosed
         * @param text {@code non-null;} annotation text
         */
        public Annotation(int start, int end, String text) {
            this.start = start;
            this.end = end;
            this.text = text;
        }

        /**
         * Constructs an instance. It is initally unclosed.
         *
         * @param start {@code >= 0;} start of annotated range
         * @param text {@code non-null;} annotation text
         */
        public Annotation(int start, String text) {
            this(start, Integer.MAX_VALUE, text);
        }

        /**
         * Sets the end as given, but only if the instance is unclosed;
         * otherwise, do nothing.
         *
         * @param end {@code >= start;} the end
         */
        public void setEndIfUnset(int end) {
            if (this.end == Integer.MAX_VALUE) {
                this.end = end;
            }
        }

        /**
         * Sets the end as given.
         *
         * @param end {@code >= start;} the end
         */
        public void setEnd(int end) {
            this.end = end;
        }

        /**
         * Gets the start.
         *
         * @return the start
         */
        public int getStart() {
            return start;
        }

        /**
         * Gets the end.
         *
         * @return the end
         */
        public int getEnd() {
            return end;
        }

        /**
         * Gets the text.
         *
         * @return {@code non-null;} the text
         */
        public String getText() {
            return text;
        }
    }
}
