/*
 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.java.util.jar.pack;

import java.io.*;
import java.util.*;
import com.sun.java.util.jar.pack.ConstantPool.*;

/**
 * Collection of relocatable constant pool references.
 * It operates with respect to a particular byte array,
 * and stores some of its state in the bytes themselves.
 * <p>
 * As a Collection, it can be iterated over, but it is not a List,
 * since it does not natively support indexed access.
 * <p>
 *
 * @author John Rose
 */
class Fixups extends AbstractCollection implements Constants {
    byte[] bytes;    // the subject of the relocations
    int head;        // desc locating first reloc
    int tail;        // desc locating last reloc
    int size;        // number of relocations
    Entry[] entries; // [0..size-1] relocations
    int[] bigDescs;  // descs which cannot be stored in the bytes

    // A "desc" (descriptor) is a bit-encoded pair of a location
    // and format.  Every fixup occurs at a "desc".  Until final
    // patching, bytes addressed by descs may also be used to
    // link this data structure together.  If the bytes are missing,
    // or if the "desc" is too large to encode in the bytes,
    // it is kept in the bigDescs array.

    Fixups(byte[] bytes) {
        this.bytes = bytes;
        entries = new Entry[3];
        bigDescs = noBigDescs;
    }
    Fixups() {
        // If there are no bytes, all descs are kept in bigDescs.
        this((byte[])null);
    }
    Fixups(byte[] bytes, Collection fixups) {
        this(bytes);
        addAll(fixups);
    }
    Fixups(Collection fixups) {
        this((byte[])null);
        addAll(fixups);
    }

    private static final int MINBIGSIZE = 1;
    // cleverly share empty bigDescs:
    private static int[] noBigDescs = {MINBIGSIZE};

    public int size() {
        return size;
    }

    public void trimToSize() {
        if (size != entries.length) {
            Entry[] oldEntries = entries;
            entries = new Entry[size];
            System.arraycopy(oldEntries, 0, entries, 0, size);
        }
        int bigSize = bigDescs[BIGSIZE];
        if (bigSize == MINBIGSIZE) {
            bigDescs = noBigDescs;
        } else if (bigSize != bigDescs.length) {
            int[] oldBigDescs = bigDescs;
            bigDescs = new int[bigSize];
            System.arraycopy(oldBigDescs, 0, bigDescs, 0, bigSize);
        }
    }

    public void visitRefs(Collection refs) {
        for (int i = 0; i < size; i++) {
            refs.add(entries[i]);
        }
    }

    public void clear() {
        if (bytes != null) {
            // Clean the bytes:
            for (Iterator i = iterator(); i.hasNext(); ) {
                Fixup fx = (Fixup) i.next();
                //System.out.println("clean "+fx);
                storeIndex(fx.location(), fx.format(), 0);
            }
        }
        size = 0;
        if (bigDescs != noBigDescs)
            bigDescs[BIGSIZE] = MINBIGSIZE;
        // do not trim to size, however
    }

    public byte[] getBytes() {
        return bytes;
    }

    public void setBytes(byte[] newBytes) {
        if (bytes == newBytes)  return;
        ArrayList old = null;
        assert((old = new ArrayList(this)) != null);
        if (bytes == null || newBytes == null) {
            // One or the other representations is deficient.
            // Construct a checkpoint.
            ArrayList save = new ArrayList(this);
            clear();
            bytes = newBytes;
            addAll(save);
        } else {
            // assume newBytes is some sort of bitwise copy of the old bytes
            bytes = newBytes;
        }
        assert(old.equals(new ArrayList(this)));
    }

    static final int LOC_SHIFT = 1;
    static final int FMT_MASK = 0x1;
    static final byte UNUSED_BYTE = 0;
    static final byte OVERFLOW_BYTE = -1;
    // fill pointer of bigDescs array is in element [0]
    static final int BIGSIZE = 0;

    // Format values:
    public static final int U2_FORMAT = 0;
    public static final int U1_FORMAT = 1;

    // Special values for the static methods.
    private static final int SPECIAL_LOC = 0;
    private static final int SPECIAL_FMT = U2_FORMAT;

    static int fmtLen(int fmt) { return 1+(fmt-U1_FORMAT)/(U2_FORMAT-U1_FORMAT); }
    static int descLoc(int desc) { return desc >>> LOC_SHIFT; }
    static int descFmt(int desc) { return desc  &  FMT_MASK; }
    static int descEnd(int desc) { return descLoc(desc) + fmtLen(descFmt(desc)); }
    static int makeDesc(int loc, int fmt) {
        int desc = (loc << LOC_SHIFT) | fmt;
        assert(descLoc(desc) == loc);
        assert(descFmt(desc) == fmt);
        return desc;
    }
    int fetchDesc(int loc, int fmt) {
        byte b1 = bytes[loc];
        assert(b1 != OVERFLOW_BYTE);
        int value;
        if (fmt == U2_FORMAT) {
            byte b2 = bytes[loc+1];
            value = ((b1 & 0xFF) << 8) + (b2 & 0xFF);
        } else {
            value = (b1 & 0xFF);
        }
        // Stored loc field is difference between its own loc and next loc.
        return value + (loc << LOC_SHIFT);
    }
    boolean storeDesc(int loc, int fmt, int desc) {
        if (bytes == null)
            return false;
        int value = desc - (loc << LOC_SHIFT);
        byte b1, b2;
        switch (fmt) {
        case U2_FORMAT:
            assert(bytes[loc+0] == UNUSED_BYTE);
            assert(bytes[loc+1] == UNUSED_BYTE);
            b1 = (byte)(value >> 8);
            b2 = (byte)(value >> 0);
            if (value == (value & 0xFFFF) && b1 != OVERFLOW_BYTE) {
                bytes[loc+0] = b1;
                bytes[loc+1] = b2;
                assert(fetchDesc(loc, fmt) == desc);
                return true;
            }
            break;
        case U1_FORMAT:
            assert(bytes[loc] == UNUSED_BYTE);
            b1 = (byte)value;
            if (value == (value & 0xFF) && b1 != OVERFLOW_BYTE) {
                bytes[loc] = b1;
                assert(fetchDesc(loc, fmt) == desc);
                return true;
            }
            break;
        default: assert(false);
        }
        // Failure.  Caller must allocate a bigDesc.
        bytes[loc] = OVERFLOW_BYTE;
        assert(fmt==U1_FORMAT || (bytes[loc+1]=(byte)bigDescs[BIGSIZE])!=999);
        return false;
    }
    void storeIndex(int loc, int fmt, int value) {
        storeIndex(bytes, loc, fmt, value);
    }
    static
    void storeIndex(byte[] bytes, int loc, int fmt, int value) {
        switch (fmt) {
        case U2_FORMAT:
            assert(value == (value & 0xFFFF)) : (value);
            bytes[loc+0] = (byte)(value >> 8);
            bytes[loc+1] = (byte)(value >> 0);
            break;
        case U1_FORMAT:
            assert(value == (value & 0xFF)) : (value);
            bytes[loc] = (byte)value;
            break;
        default: assert(false);
        }
    }

    /** Simple and necessary tuple to present each fixup. */
    public static
    class Fixup implements Comparable {
        int desc;         // location and format of reloc
        Entry entry;      // which entry to plug into the bytes
        Fixup(int desc, Entry entry) {
            this.desc = desc;
            this.entry = entry;
        }
        public Fixup(int loc, int fmt, Entry entry) {
            this.desc = makeDesc(loc, fmt);
            this.entry = entry;
        }
        public int location() { return descLoc(desc); }
        public int format() { return descFmt(desc); }
        public Entry entry() { return entry; }
        public int compareTo(Fixup that) {
            // Ordering depends only on location.
            return this.location() - that.location();
        }
        public int compareTo(Object that) {
            return compareTo((Fixup)that);
        }
        public boolean equals(Object x) {
            if (!(x instanceof Fixup))  return false;
            Fixup that = (Fixup) x;
            return this.desc == that.desc && this.entry == that.entry;
        }
        public String toString() {
            return "@"+location()+(format()==U1_FORMAT?".1":"")+"="+entry;
        }
    }

    private
    class Itr implements Iterator {
        int index = 0;               // index into entries
        int bigIndex = BIGSIZE+1;    // index into bigDescs
        int next = head;             // desc pointing to next fixup
        public boolean hasNext() { return index < size; }
        public void remove() { throw new UnsupportedOperationException(); }
        public Object next() {
            int thisIndex = index;
            return new Fixup(nextDesc(), entries[thisIndex]);
        }
        int nextDesc() {
            int thisIndex = index++;
            int thisDesc = next;
            if (index < size) {
                // Fetch next desc eagerly, in case this fixup gets finalized.
                int loc = descLoc(thisDesc);
                int fmt = descFmt(thisDesc);
                if (bytes != null && bytes[loc] != OVERFLOW_BYTE) {
                    next = fetchDesc(loc, fmt);
                } else {
                    // The unused extra byte is "asserted" to be equal to BI.
                    // This helps keep the overflow descs in sync.
                    assert(fmt==U1_FORMAT || bytes == null || bytes[loc+1]==(byte)bigIndex);
                    next = bigDescs[bigIndex++];
                }
            }
            return thisDesc;
        }
    }

    public Iterator iterator() {
        return new Itr();
    }
    public void add(int location, int format, Entry entry) {
        addDesc(makeDesc(location, format), entry);
    }
    public boolean add(Fixup f) {
        addDesc(f.desc, f.entry);
        return true;
    }
    public boolean add(Object fixup) {
        return add((Fixup) fixup);
    }
    public boolean addAll(Collection c) {
        if (c instanceof Fixups) {
            // Use knowledge of Itr structure to avoid building little structs.
            Fixups that = (Fixups) c;
            if (that.size == 0)  return false;
            if (this.size == 0 && entries.length < that.size)
                growEntries(that.size);  // presize exactly
            Entry[] thatEntries = that.entries;
            for (Itr i = that.new Itr(); i.hasNext(); ) {
                int ni = i.index;
                addDesc(i.nextDesc(), thatEntries[ni]);
            }
            return true;
        } else {
            return super.addAll(c);
        }
    }
    // Here is how things get added:
    private void addDesc(int thisDesc, Entry entry) {
        if (entries.length == size)
            growEntries(size * 2);
        entries[size] = entry;
        if (size == 0) {
            head = tail = thisDesc;
        } else {
            int prevDesc = tail;
            // Store new desc in previous tail.
            int prevLoc = descLoc(prevDesc);
            int prevFmt = descFmt(prevDesc);
            int prevLen = fmtLen(prevFmt);
            int thisLoc = descLoc(thisDesc);
            // The collection must go in ascending order, and not overlap.
            if (thisLoc < prevLoc + prevLen)
                badOverlap(thisLoc);
            tail = thisDesc;
            if (!storeDesc(prevLoc, prevFmt, thisDesc)) {
                // overflow
                int bigSize = bigDescs[BIGSIZE];
                if (bigDescs.length == bigSize)
                    growBigDescs();
                //System.out.println("bigDescs["+bigSize+"] = "+thisDesc);
                bigDescs[bigSize++] = thisDesc;
                bigDescs[BIGSIZE] = bigSize;
            }
        }
        size += 1;
    }
    private void badOverlap(int thisLoc) {
        throw new IllegalArgumentException("locs must be ascending and must not overlap:  "+thisLoc+" >> "+this);
    }

    private void growEntries(int newSize) {
        Entry[] oldEntries = entries;
        entries = new Entry[Math.max(3, newSize)];
        System.arraycopy(oldEntries, 0, entries, 0, oldEntries.length);
    }
    private void growBigDescs() {
        int[] oldBigDescs = bigDescs;
        bigDescs = new int[oldBigDescs.length * 2];
        System.arraycopy(oldBigDescs, 0, bigDescs, 0, oldBigDescs.length);
    }

    /// Static methods that optimize the use of this class.
    public static
    Object add(Object prevFixups,
               byte[] bytes, int loc, int fmt,
               Entry e) {
        Fixups f;
        if (prevFixups == null) {
            if (loc == SPECIAL_LOC && fmt == SPECIAL_FMT) {
                // Special convention:  If the attribute has a
                // U2 relocation at position zero, store the Entry
                // rather than building a Fixups structure.
                return e;
            }
            f = new Fixups(bytes);
        } else if (!(prevFixups instanceof Fixups)) {
            // Recognize the special convention:
            Entry firstEntry = (Entry) prevFixups;
            f = new Fixups(bytes);
            f.add(SPECIAL_LOC, SPECIAL_FMT, firstEntry);
        } else {
            f = (Fixups) prevFixups;
            assert(f.bytes == bytes);
        }
        f.add(loc, fmt, e);
        return f;
    }

    public static
    void setBytes(Object fixups, byte[] bytes) {
        if (fixups instanceof Fixups) {
            Fixups f = (Fixups) fixups;
            f.setBytes(bytes);
        }
    }

    public static
    Object trimToSize(Object fixups) {
        if (fixups instanceof Fixups) {
            Fixups f = (Fixups) fixups;
            f.trimToSize();
            if (f.size() == 0)
                fixups = null;
        }
        return fixups;
    }

    // Iterate over all the references in this set of fixups.
    public static
    void visitRefs(Object fixups, Collection refs) {
        if (fixups == null) {
        } else if (!(fixups instanceof Fixups)) {
            // Special convention; see above.
            refs.add((Entry) fixups);
        } else {
            Fixups f = (Fixups) fixups;
            f.visitRefs(refs);
        }
    }

    // Clear out this set of fixups by replacing each reference
    // by a hardcoded coding of its reference, drawn from ix.
    public static
    void finishRefs(Object fixups, byte[] bytes, ConstantPool.Index ix) {
        if (fixups == null)
            return;
        if (!(fixups instanceof Fixups)) {
            // Special convention; see above.
            int index = ix.indexOf((Entry) fixups);
            storeIndex(bytes, SPECIAL_LOC, SPECIAL_FMT, index);
            return;
        }
        Fixups f = (Fixups) fixups;
        assert(f.bytes == bytes);
        f.finishRefs(ix);
    }

    void finishRefs(ConstantPool.Index ix) {
        if (isEmpty())
            return;
        for (Iterator i = iterator(); i.hasNext(); ) {
            Fixup fx = (Fixup) i.next();
            int index = ix.indexOf(fx.entry);
            //System.out.println("finish "+fx+" = "+index);
            // Note that the iterator has already fetched the
            // bytes we are about to overwrite.
            storeIndex(fx.location(), fx.format(), index);
        }
        // Further iterations should do nothing:
        bytes = null;  // do not clean them
        clear();
    }

/*
    /// Testing.
    public static void main(String[] av) {
        byte[] bytes = new byte[1 << 20];
        ConstantPool cp = new ConstantPool();
        Fixups f = new Fixups(bytes);
        boolean isU1 = false;
        int span = 3;
        int nextLoc = 0;
        int[] locs = new int[100];
        final int[] indexes = new int[100];
        int iptr = 1;
        for (int loc = 0; loc < bytes.length; loc++) {
            if (loc == nextLoc && loc+1 < bytes.length) {
                int fmt = (isU1 ? U1_FORMAT : U2_FORMAT);
                Entry e = ConstantPool.getUtf8Entry("L"+loc);
                f.add(loc, fmt, e);
                isU1 ^= true;
                if (iptr < 10) {
                    // Make it close in.
                    nextLoc += fmtLen(fmt) + (iptr < 5 ? 0 : 1);
                } else {
                    nextLoc += span;
                    span = (int)(span * 1.77);
                }
                // Here are the bytes that would have gone here:
                locs[iptr] = loc;
                if (fmt == U1_FORMAT) {
                    indexes[iptr++] = (loc & 0xFF);
                } else {
                    indexes[iptr++] = ((loc & 0xFF) << 8) | ((loc+1) & 0xFF);
                    ++loc;  // skip a byte
                }
                continue;
            }
            bytes[loc] = (byte)loc;
        }
        System.out.println("size="+f.size()
                           +" overflow="+(f.bigDescs[BIGSIZE]-1));
        System.out.println("Fixups: "+f);
        // Test collection contents.
        assert(iptr == 1+f.size());
        List l = new ArrayList(f);
        Collections.sort(l);  // should not change the order
        if (!l.equals(new ArrayList(f)))  System.out.println("** disordered");
        f.setBytes(null);
        if (!l.equals(new ArrayList(f)))  System.out.println("** bad set 1");
        f.setBytes(bytes);
        if (!l.equals(new ArrayList(f)))  System.out.println("** bad set 2");
        Fixups f3 = new Fixups(f);
        if (!l.equals(new ArrayList(f3))) System.out.println("** bad set 3");
        Iterator fi = f.iterator();
        for (int i = 1; i < iptr; i++) {
            Fixup fx = (Fixup) fi.next();
            if (fx.location() != locs[i]) {
                System.out.println("** "+fx+" != "+locs[i]);
            }
            if (fx.format() == U1_FORMAT)
                System.out.println(fx+" -> "+bytes[locs[i]]);
            else
                System.out.println(fx+" -> "+bytes[locs[i]]+" "+bytes[locs[i]+1]);
        }
        assert(!fi.hasNext());
        indexes[0] = 1;  // like iptr
        Index ix = new Index("ix") {
            public int indexOf(Entry e) {
                return indexes[indexes[0]++];
            }
        };
        f.finishRefs(ix);
        for (int loc = 0; loc < bytes.length; loc++) {
            if (bytes[loc] != (byte)loc) {
                System.out.println("** ["+loc+"] = "+bytes[loc]+" != "+(byte)loc);
            }
        }
    }
//*/
}
