/*
 * Copyright 2001-2003 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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.Package.Class;
import com.sun.java.util.jar.pack.Package.InnerClass;
import com.sun.java.util.jar.pack.ConstantPool.*;

/**
 * Writer for a class file that is incorporated into a package.
 * @author John Rose
 */
class ClassWriter implements Constants {
    int verbose;

    Package pkg;
    Class cls;
    DataOutputStream out;
    Index cpIndex;

    ClassWriter(Class cls, OutputStream out) throws IOException {
        this.pkg = cls.getPackage();
        this.cls = cls;
        this.verbose = pkg.verbose;
        this.out = new DataOutputStream(new BufferedOutputStream(out));
        this.cpIndex = ConstantPool.makeIndex(cls.toString(), cls.getCPMap());
        this.cpIndex.flattenSigs = true;
        if (verbose > 1)
            Utils.log.fine("local CP="+(verbose > 2 ? cpIndex.dumpString() : cpIndex.toString()));
    }

    private void writeShort(int x) throws IOException {
        out.writeShort(x);
    }

    private void writeInt(int x) throws IOException {
        out.writeInt(x);
    }

    /** Write a 2-byte int representing a CP entry, using the local cpIndex. */
    private void writeRef(Entry e) throws IOException {
        int i = (e == null) ? 0 : cpIndex.indexOf(e);
        writeShort(i);
    }

    void write() throws IOException {
        boolean ok = false;
        try {
            if (verbose > 1)  Utils.log.fine("...writing "+cls);
            writeMagicNumbers();
            writeConstantPool();
            writeHeader();
            writeMembers(false);  // fields
            writeMembers(true);   // methods
            writeAttributes(ATTR_CONTEXT_CLASS, cls);
            /* Closing here will cause all the underlying
               streams to close, Causing the jar stream
               to close prematurely, instead we just flush.
               out.close();
             */
            out.flush();
            ok = true;
        } finally {
            if (!ok) {
                Utils.log.warning("Error on output of "+cls);
            }
        }
    }

    void writeMagicNumbers() throws IOException {
        writeInt(cls.magic);
        writeShort(cls.minver);
        writeShort(cls.majver);
    }

    void writeConstantPool() throws IOException {
        Entry[] cpMap = cls.cpMap;
        writeShort(cpMap.length);
        for (int i = 0; i < cpMap.length; i++) {
            Entry e = cpMap[i];
            assert((e == null) == (i == 0 || cpMap[i-1] != null && cpMap[i-1].isDoubleWord()));
            if (e == null)  continue;
            byte tag = e.getTag();
            if (verbose > 2)  Utils.log.fine("   CP["+i+"] = "+e);
            out.write(tag);
            switch (tag) {
                case CONSTANT_Signature:
                    assert(false);  // should not reach here
                    break;
                case CONSTANT_Utf8:
                    out.writeUTF(e.stringValue());
                    break;
                case CONSTANT_Integer:
                    out.writeInt(((NumberEntry)e).numberValue().intValue());
                    break;
                case CONSTANT_Float:
                    float fval = ((NumberEntry)e).numberValue().floatValue();
                    out.writeInt(Float.floatToRawIntBits(fval));
                    break;
                case CONSTANT_Long:
                    out.writeLong(((NumberEntry)e).numberValue().longValue());
                    break;
                case CONSTANT_Double:
                    double dval = ((NumberEntry)e).numberValue().doubleValue();
                    out.writeLong(Double.doubleToRawLongBits(dval));
                    break;
                case CONSTANT_Class:
                case CONSTANT_String:
                    writeRef(e.getRef(0));
                    break;
                case CONSTANT_Fieldref:
                case CONSTANT_Methodref:
                case CONSTANT_InterfaceMethodref:
                case CONSTANT_NameandType:
                    writeRef(e.getRef(0));
                    writeRef(e.getRef(1));
                    break;
                default:
                    throw new IOException("Bad constant pool tag "+tag);
            }
        }
    }

    void writeHeader() throws IOException {
        writeShort(cls.flags);
        writeRef(cls.thisClass);
        writeRef(cls.superClass);
        writeShort(cls.interfaces.length);
        for (int i = 0; i < cls.interfaces.length; i++) {
            writeRef(cls.interfaces[i]);
        }
    }

    void writeMembers(boolean doMethods) throws IOException {
        List mems;
        if (!doMethods)
            mems = cls.getFields();
        else
            mems = cls.getMethods();
        writeShort(mems.size());
        for (Iterator i = mems.iterator(); i.hasNext(); ) {
            Class.Member m = (Class.Member) i.next();
            writeMember(m, doMethods);
        }
    }

    void writeMember(Class.Member m, boolean doMethod) throws IOException {
        if (verbose > 2)  Utils.log.fine("writeMember "+m);
        writeShort(m.flags);
        writeRef(m.getDescriptor().nameRef);
        writeRef(m.getDescriptor().typeRef);
        writeAttributes(!doMethod ? ATTR_CONTEXT_FIELD : ATTR_CONTEXT_METHOD,
                        m);
    }

    // handy buffer for collecting attrs
    ByteArrayOutputStream buf    = new ByteArrayOutputStream();
    DataOutputStream      bufOut = new DataOutputStream(buf);

    void writeAttributes(int ctype, Attribute.Holder h) throws IOException {
        if (h.attributes == null) {
            writeShort(0);  // attribute size
            return;
        }
        writeShort(h.attributes.size());
        for (Iterator i = h.attributes.iterator(); i.hasNext(); ) {
            Attribute a = (Attribute) i.next();
            a.finishRefs(cpIndex);
            writeRef(a.getNameRef());
            if (a.layout() == Package.attrCodeEmpty ||
                a.layout() == Package.attrInnerClassesEmpty) {
                // These are hardwired.
                DataOutputStream savedOut = out;
                assert(out != bufOut);
                buf.reset();
                out = bufOut;
                if (a.name() == "Code") {
                    Class.Method m = (Class.Method) h;
                    writeCode(m.code);
                } else {
                    assert(h == cls);
                    writeInnerClasses(cls);
                }
                out = savedOut;
                if (verbose > 2)
                    Utils.log.fine("Attribute "+a.name()+" ["+buf.size()+"]");
                writeInt(buf.size());
                buf.writeTo(out);
            } else {
                if (verbose > 2)
                    Utils.log.fine("Attribute "+a.name()+" ["+a.size()+"]");
                writeInt(a.size());
                out.write(a.bytes());
            }
        }
    }

    void writeCode(Code code) throws IOException {
        code.finishRefs(cpIndex);
        writeShort(code.max_stack);
        writeShort(code.max_locals);
        writeInt(code.bytes.length);
        out.write(code.bytes);
        int nh = code.getHandlerCount();
        writeShort(nh);
        for (int i = 0; i < nh; i++) {
             writeShort(code.handler_start[i]);
             writeShort(code.handler_end[i]);
             writeShort(code.handler_catch[i]);
             writeRef(code.handler_class[i]);
        }
        writeAttributes(ATTR_CONTEXT_CODE, code);
    }

    void writeInnerClasses(Class cls) throws IOException {
        List ics = cls.getInnerClasses();
        writeShort(ics.size());
        for (Iterator i = ics.iterator(); i.hasNext(); ) {
            InnerClass ic = (InnerClass) i.next();
            writeRef(ic.thisClass);
            writeRef(ic.outerClass);
            writeRef(ic.name);
            writeShort(ic.flags);
        }
    }
}
