/*
 * Copyright (c) 2012, 2013, 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.lir;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.EnumSet;

import org.graalvm.compiler.core.common.Fields;
import org.graalvm.compiler.core.common.FieldsScanner;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
import org.graalvm.compiler.lir.LIRInstruction.OperandMode;

import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.meta.Value;

public class LIRInstructionClass<T> extends LIRIntrospection<T> {

    public static <T extends LIRInstruction> LIRInstructionClass<T> create(Class<T> c) {
        return new LIRInstructionClass<>(c);
    }

    private static final Class<LIRInstruction> INSTRUCTION_CLASS = LIRInstruction.class;
    private static final Class<LIRFrameState> STATE_CLASS = LIRFrameState.class;

    private final Values uses;
    private final Values alives;
    private final Values temps;
    private final Values defs;
    private final Fields states;

    private String opcodeConstant;
    private int opcodeIndex;

    private LIRInstructionClass(Class<T> clazz) {
        this(clazz, new FieldsScanner.DefaultCalcOffset());
    }

    public LIRInstructionClass(Class<T> clazz, FieldsScanner.CalcOffset calcOffset) {
        super(clazz);
        assert INSTRUCTION_CLASS.isAssignableFrom(clazz);

        LIRInstructionFieldsScanner ifs = new LIRInstructionFieldsScanner(calcOffset);
        ifs.scan(clazz);

        uses = new Values(ifs.valueAnnotations.get(LIRInstruction.Use.class));
        alives = new Values(ifs.valueAnnotations.get(LIRInstruction.Alive.class));
        temps = new Values(ifs.valueAnnotations.get(LIRInstruction.Temp.class));
        defs = new Values(ifs.valueAnnotations.get(LIRInstruction.Def.class));

        states = new Fields(ifs.states);
        data = new Fields(ifs.data);

        opcodeConstant = ifs.opcodeConstant;
        if (ifs.opcodeField == null) {
            opcodeIndex = -1;
        } else {
            opcodeIndex = ifs.data.indexOf(ifs.opcodeField);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> LIRInstructionClass<T> get(Class<T> clazz) {
        try {
            Field field = clazz.getDeclaredField("TYPE");
            field.setAccessible(true);
            return (LIRInstructionClass<T>) field.get(null);
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            throw new RuntimeException(e);
        }
    }

    private static class LIRInstructionFieldsScanner extends LIRFieldsScanner {

        private String opcodeConstant;

        /**
         * Field (if any) annotated by {@link Opcode}.
         */
        private FieldsScanner.FieldInfo opcodeField;

        LIRInstructionFieldsScanner(FieldsScanner.CalcOffset calc) {
            super(calc);

            valueAnnotations.put(LIRInstruction.Use.class, new OperandModeAnnotation());
            valueAnnotations.put(LIRInstruction.Alive.class, new OperandModeAnnotation());
            valueAnnotations.put(LIRInstruction.Temp.class, new OperandModeAnnotation());
            valueAnnotations.put(LIRInstruction.Def.class, new OperandModeAnnotation());
        }

        @Override
        protected EnumSet<OperandFlag> getFlags(Field field) {
            EnumSet<OperandFlag> result = EnumSet.noneOf(OperandFlag.class);
            // Unfortunately, annotations cannot have class hierarchies or implement interfaces, so
            // we have to duplicate the code for every operand mode.
            // Unfortunately, annotations cannot have an EnumSet property, so we have to convert
            // from arrays to EnumSet manually.
            if (field.isAnnotationPresent(LIRInstruction.Use.class)) {
                result.addAll(Arrays.asList(field.getAnnotation(LIRInstruction.Use.class).value()));
            } else if (field.isAnnotationPresent(LIRInstruction.Alive.class)) {
                result.addAll(Arrays.asList(field.getAnnotation(LIRInstruction.Alive.class).value()));
            } else if (field.isAnnotationPresent(LIRInstruction.Temp.class)) {
                result.addAll(Arrays.asList(field.getAnnotation(LIRInstruction.Temp.class).value()));
            } else if (field.isAnnotationPresent(LIRInstruction.Def.class)) {
                result.addAll(Arrays.asList(field.getAnnotation(LIRInstruction.Def.class).value()));
            } else {
                GraalError.shouldNotReachHere();
            }
            return result;
        }

        public void scan(Class<?> clazz) {
            if (clazz.getAnnotation(Opcode.class) != null) {
                opcodeConstant = clazz.getAnnotation(Opcode.class).value();
            }
            opcodeField = null;

            super.scan(clazz, LIRInstruction.class, false);

            if (opcodeConstant == null && opcodeField == null) {
                opcodeConstant = clazz.getSimpleName();
                if (opcodeConstant.endsWith("Op")) {
                    opcodeConstant = opcodeConstant.substring(0, opcodeConstant.length() - 2);
                }
            }
        }

        @Override
        protected void scanField(Field field, long offset) {
            Class<?> type = field.getType();
            if (STATE_CLASS.isAssignableFrom(type)) {
                assert getOperandModeAnnotation(field) == null : "Field must not have operand mode annotation: " + field;
                assert field.getAnnotation(LIRInstruction.State.class) != null : "Field must have state annotation: " + field;
                states.add(new FieldsScanner.FieldInfo(offset, field.getName(), type, field.getDeclaringClass()));
            } else {
                super.scanField(field, offset);
            }

            if (field.getAnnotation(Opcode.class) != null) {
                assert opcodeConstant == null && opcodeField == null : "Can have only one Opcode definition: " + type;
                assert data.get(data.size() - 1).offset == offset;
                opcodeField = data.get(data.size() - 1);
            }
        }
    }

    @Override
    public Fields[] getAllFields() {
        assert values == null;
        return new Fields[]{data, uses, alives, temps, defs, states};
    }

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" use[");
        uses.appendFields(str);
        str.append("] alive[");
        alives.appendFields(str);
        str.append("] temp[");
        temps.appendFields(str);
        str.append("] def[");
        defs.appendFields(str);
        str.append("] state[");
        states.appendFields(str);
        str.append("] data[");
        data.appendFields(str);
        str.append("]");
        return str.toString();
    }

    Values getValues(OperandMode mode) {
        switch (mode) {
            case USE:
                return uses;
            case ALIVE:
                return alives;
            case TEMP:
                return temps;
            case DEF:
                return defs;
            default:
                throw GraalError.shouldNotReachHere("unknown OperandMode: " + mode);
        }
    }

    final String getOpcode(LIRInstruction obj) {
        if (opcodeConstant != null) {
            return opcodeConstant;
        }
        assert opcodeIndex != -1;
        return String.valueOf(data.getObject(obj, opcodeIndex));
    }

    final boolean hasOperands() {
        return uses.getCount() > 0 || alives.getCount() > 0 || temps.getCount() > 0 || defs.getCount() > 0;
    }

    final boolean hasState(LIRInstruction obj) {
        for (int i = 0; i < states.getCount(); i++) {
            if (states.getObject(obj, i) != null) {
                return true;
            }
        }
        return false;
    }

    final void forEachUse(LIRInstruction obj, InstructionValueProcedure proc) {
        forEach(obj, uses, OperandMode.USE, proc);
    }

    final void forEachAlive(LIRInstruction obj, InstructionValueProcedure proc) {
        forEach(obj, alives, OperandMode.ALIVE, proc);
    }

    final void forEachTemp(LIRInstruction obj, InstructionValueProcedure proc) {
        forEach(obj, temps, OperandMode.TEMP, proc);
    }

    final void forEachDef(LIRInstruction obj, InstructionValueProcedure proc) {
        forEach(obj, defs, OperandMode.DEF, proc);
    }

    final void visitEachUse(LIRInstruction obj, InstructionValueConsumer proc) {
        visitEach(obj, uses, OperandMode.USE, proc);
    }

    final void visitEachAlive(LIRInstruction obj, InstructionValueConsumer proc) {
        visitEach(obj, alives, OperandMode.ALIVE, proc);
    }

    final void visitEachTemp(LIRInstruction obj, InstructionValueConsumer proc) {
        visitEach(obj, temps, OperandMode.TEMP, proc);
    }

    final void visitEachDef(LIRInstruction obj, InstructionValueConsumer proc) {
        visitEach(obj, defs, OperandMode.DEF, proc);
    }

    final void forEachState(LIRInstruction obj, InstructionValueProcedure proc) {
        for (int i = 0; i < states.getCount(); i++) {
            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
            if (state != null) {
                state.forEachState(obj, proc);
            }
        }
    }

    final void visitEachState(LIRInstruction obj, InstructionValueConsumer proc) {
        for (int i = 0; i < states.getCount(); i++) {
            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
            if (state != null) {
                state.visitEachState(obj, proc);
            }
        }
    }

    final void forEachState(LIRInstruction obj, InstructionStateProcedure proc) {
        for (int i = 0; i < states.getCount(); i++) {
            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
            if (state != null) {
                proc.doState(obj, state);
            }
        }
    }

    final Value forEachRegisterHint(LIRInstruction obj, OperandMode mode, InstructionValueProcedure proc) {
        Values hints;
        if (mode == OperandMode.USE) {
            hints = defs;
        } else if (mode == OperandMode.DEF) {
            hints = uses;
        } else {
            return null;
        }

        for (int i = 0; i < hints.getCount(); i++) {
            if (i < hints.getDirectCount()) {
                Value hintValue = hints.getValue(obj, i);
                Value result = proc.doValue(obj, hintValue, null, null);
                if (result != null) {
                    return result;
                }
            } else {
                Value[] hintValues = hints.getValueArray(obj, i);
                for (int j = 0; j < hintValues.length; j++) {
                    Value hintValue = hintValues[j];
                    Value result = proc.doValue(obj, hintValue, null, null);
                    if (result != null) {
                        return result;
                    }
                }
            }
        }
        return null;
    }

    String toString(LIRInstruction obj) {
        StringBuilder result = new StringBuilder();

        appendValues(result, obj, "", " = ", "(", ")", new String[]{""}, defs);
        result.append(String.valueOf(getOpcode(obj)).toUpperCase());
        appendValues(result, obj, " ", "", "(", ")", new String[]{"", "~"}, uses, alives);
        appendValues(result, obj, " ", "", "{", "}", new String[]{""}, temps);

        for (int i = 0; i < data.getCount(); i++) {
            if (i == opcodeIndex) {
                continue;
            }
            result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data));
        }

        for (int i = 0; i < states.getCount(); i++) {
            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
            if (state != null) {
                result.append(" ").append(states.getName(i)).append(" [bci:");
                String sep = "";
                for (BytecodeFrame cur = state.topFrame; cur != null; cur = cur.caller()) {
                    result.append(sep).append(cur.getBCI());
                    sep = ", ";
                }
                result.append("]");
            }
        }

        return result.toString();
    }
}
