/*
 * 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.dexgen.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 {
    /** 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(new byte[DEFAULT_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 writeUnsignedLeb128(int value) {
        int remaining = value >> 7;
        int count = 0;

        while (remaining != 0) {
            writeByte((value & 0x7f) | 0x80);
            value = remaining;
            remaining >>= 7;
            count++;
        }

        writeByte(value & 0x7f);
        return count + 1;
    }

    /** {@inheritDoc} */
    public int writeSignedLeb128(int value) {
        int remaining = value >> 7;
        int count = 0;
        boolean hasMore = true;
        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;

        while (hasMore) {
            hasMore = (remaining != end)
                || ((remaining & 1) != ((value >> 6) & 1));

            writeByte((value & 0x7f) | (hasMore ? 0x80 : 0));
            value = remaining;
            remaining >>= 7;
            count++;
        }

        return count;
    }

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