/*
 * Copyright (c) 2016, 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.
 *
 * 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 org.graalvm.compiler.replacements.classfile;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.instrument.Instrumentation;

import org.graalvm.compiler.bytecode.Bytecode;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.replacements.classfile.ClassfileConstant.Utf8;

import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.DefaultProfilingInfo;
import jdk.vm.ci.meta.ExceptionHandler;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LineNumberTable;
import jdk.vm.ci.meta.Local;
import jdk.vm.ci.meta.LocalVariableTable;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.TriState;

/**
 * The bytecode properties of a method as parsed directly from a class file without any
 * {@linkplain Instrumentation instrumentation} or other rewriting performed on the bytecode.
 */
public class ClassfileBytecode implements Bytecode {

    private static final int EXCEPTION_HANDLER_TABLE_SIZE_IN_BYTES = 8;
    private static final int LINE_NUMBER_TABLE_ENTRY_SIZE_IN_BYTES = 4;
    private static final int LOCAL_VARIABLE_TABLE_SIZE_IN_BYTES = 10;

    private final ResolvedJavaMethod method;

    private final ClassfileConstantPool constantPool;

    private byte[] code;
    private int maxLocals;
    private int maxStack;

    private byte[] exceptionTableBytes;
    private byte[] lineNumberTableBytes;
    private byte[] localVariableTableBytes;

    public ClassfileBytecode(ResolvedJavaMethod method, DataInputStream stream, ClassfileConstantPool constantPool) throws IOException {
        this.method = method;
        this.constantPool = constantPool;
        maxStack = stream.readUnsignedShort();
        maxLocals = stream.readUnsignedShort();
        int codeLength = stream.readInt();
        code = new byte[codeLength];
        stream.readFully(code);
        int exceptionTableLength = stream.readUnsignedShort();
        exceptionTableBytes = new byte[exceptionTableLength * EXCEPTION_HANDLER_TABLE_SIZE_IN_BYTES];
        stream.readFully(exceptionTableBytes);
        readCodeAttributes(stream);
    }

    private void readCodeAttributes(DataInputStream stream) throws IOException {
        int count = stream.readUnsignedShort();
        for (int i = 0; i < count; i++) {
            String attributeName = constantPool.get(Utf8.class, stream.readUnsignedShort()).value;
            int attributeLength = stream.readInt();
            switch (attributeName) {
                case "LocalVariableTable": {
                    int length = stream.readUnsignedShort();
                    localVariableTableBytes = new byte[length * LOCAL_VARIABLE_TABLE_SIZE_IN_BYTES];
                    stream.readFully(localVariableTableBytes);
                    break;
                }
                case "LineNumberTable": {
                    int length = stream.readUnsignedShort();
                    lineNumberTableBytes = new byte[length * LINE_NUMBER_TABLE_ENTRY_SIZE_IN_BYTES];
                    stream.readFully(lineNumberTableBytes);
                    break;
                }
                default: {
                    Classfile.skipFully(stream, attributeLength);
                    break;
                }
            }
        }
    }

    @Override
    public byte[] getCode() {
        return code;
    }

    @Override
    public int getCodeSize() {
        return code.length;
    }

    @Override
    public int getMaxLocals() {
        return maxLocals;
    }

    @Override
    public int getMaxStackSize() {
        return maxStack;
    }

    @Override
    public ExceptionHandler[] getExceptionHandlers() {
        if (exceptionTableBytes == null) {
            return new ExceptionHandler[0];
        }

        final int exceptionTableLength = exceptionTableBytes.length / EXCEPTION_HANDLER_TABLE_SIZE_IN_BYTES;
        ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
        DataInputStream stream = new DataInputStream(new ByteArrayInputStream(exceptionTableBytes));

        for (int i = 0; i < exceptionTableLength; i++) {
            try {
                final int startPc = stream.readUnsignedShort();
                final int endPc = stream.readUnsignedShort();
                final int handlerPc = stream.readUnsignedShort();
                int catchTypeIndex = stream.readUnsignedShort();

                JavaType catchType;
                if (catchTypeIndex == 0) {
                    catchType = null;
                } else {
                    final int opcode = -1;  // opcode is not used
                    catchType = constantPool.lookupType(catchTypeIndex, opcode);

                    // Check for Throwable which catches everything.
                    if (catchType.toJavaName().equals("java.lang.Throwable")) {
                        catchTypeIndex = 0;
                        catchType = null;
                    }
                }
                handlers[i] = new ExceptionHandler(startPc, endPc, handlerPc, catchTypeIndex, catchType);
            } catch (IOException e) {
                throw new GraalError(e);
            }
        }

        return handlers;
    }

    @Override
    public StackTraceElement asStackTraceElement(int bci) {
        int line = getLineNumberTable().getLineNumber(bci);
        return new StackTraceElement(method.getDeclaringClass().toJavaName(), method.getName(), method.getDeclaringClass().getSourceFileName(), line);
    }

    @Override
    public ConstantPool getConstantPool() {
        return constantPool;
    }

    @Override
    public LineNumberTable getLineNumberTable() {
        if (lineNumberTableBytes == null) {
            return null;
        }

        final int lineNumberTableLength = lineNumberTableBytes.length / LINE_NUMBER_TABLE_ENTRY_SIZE_IN_BYTES;
        DataInputStream stream = new DataInputStream(new ByteArrayInputStream(lineNumberTableBytes));
        int[] bci = new int[lineNumberTableLength];
        int[] line = new int[lineNumberTableLength];

        for (int i = 0; i < lineNumberTableLength; i++) {
            try {
                bci[i] = stream.readUnsignedShort();
                line[i] = stream.readUnsignedShort();
            } catch (IOException e) {
                throw new GraalError(e);
            }
        }

        return new LineNumberTable(line, bci);
    }

    @Override
    public LocalVariableTable getLocalVariableTable() {
        if (localVariableTableBytes == null) {
            return null;
        }

        final int localVariableTableLength = localVariableTableBytes.length / LOCAL_VARIABLE_TABLE_SIZE_IN_BYTES;
        DataInputStream stream = new DataInputStream(new ByteArrayInputStream(localVariableTableBytes));
        Local[] locals = new Local[localVariableTableLength];

        for (int i = 0; i < localVariableTableLength; i++) {
            try {
                final int startBci = stream.readUnsignedShort();
                final int endBci = startBci + stream.readUnsignedShort();
                final int nameCpIndex = stream.readUnsignedShort();
                final int typeCpIndex = stream.readUnsignedShort();
                final int slot = stream.readUnsignedShort();

                String localName = constantPool.lookupUtf8(nameCpIndex);
                String localType = constantPool.lookupUtf8(typeCpIndex);

                ClassfileBytecodeProvider context = constantPool.context;
                Class<?> c = context.resolveToClass(localType);
                locals[i] = new Local(localName, context.metaAccess.lookupJavaType(c), startBci, endBci, slot);
            } catch (IOException e) {
                throw new GraalError(e);
            }
        }

        return new LocalVariableTable(locals);
    }

    @Override
    public ResolvedJavaMethod getMethod() {
        return method;
    }

    @Override
    public ProfilingInfo getProfilingInfo() {
        return DefaultProfilingInfo.get(TriState.FALSE);
    }

    @Override
    public String toString() {
        return getClass().getName() + method.format("<%H.%n(%p)>");
    }
}
