/*
 * Copyright (c) 2001, 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.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);
        }
    }
}
