/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.rop.code;

import com.android.dx.rop.type.StdTypeList;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeList;
import com.android.dx.util.Hex;

/**
 * Class that describes all the immutable parts of register-based operations.
 */
public final class Rop {
    /** minimum {@code BRANCH_*} value */
    public static final int BRANCH_MIN = 1;

    /** indicates a non-branching op */
    public static final int BRANCH_NONE = 1;

    /** indicates a function/method return */
    public static final int BRANCH_RETURN = 2;

    /** indicates an unconditional goto */
    public static final int BRANCH_GOTO = 3;

    /** indicates a two-way branch */
    public static final int BRANCH_IF = 4;

    /** indicates a switch-style branch */
    public static final int BRANCH_SWITCH = 5;

    /** indicates a throw-style branch (both always-throws and may-throw) */
    public static final int BRANCH_THROW = 6;

    /** maximum {@code BRANCH_*} value */
    public static final int BRANCH_MAX = 6;

    /** the opcode; one of the constants in {@link RegOps} */
    private final int opcode;

    /**
     * {@code non-null;} result type of this operation; {@link Type#VOID} for
     * no-result operations 
     */
    private final Type result;

    /** {@code non-null;} types of all the sources of this operation */
    private final TypeList sources;

    /** {@code non-null;} list of possible types thrown by this operation */
    private final TypeList exceptions;

    /**
     * the branchingness of this op; one of the {@code BRANCH_*}
     * constants in this class 
     */
    private final int branchingness;

    /** whether this is a function/method call op or similar */
    private final boolean isCallLike;

    /** {@code null-ok;} nickname, if specified (used for debugging) */
    private final String nickname;

    /**
     * Constructs an instance. This method is private. Use one of the
     * public constructors.
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param result {@code non-null;} result type of this operation; {@link
     * Type#VOID} for no-result operations
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param exceptions {@code non-null;} list of possible types thrown by this
     * operation
     * @param branchingness the branchingness of this op; one of the
     * {@code BRANCH_*} constants
     * @param isCallLike whether the op is a function/method call or similar
     * @param nickname {@code null-ok;} optional nickname (used for debugging)
     */
    public Rop(int opcode, Type result, TypeList sources,
               TypeList exceptions, int branchingness, boolean isCallLike,
               String nickname) {
        if (result == null) {
            throw new NullPointerException("result == null");
        }

        if (sources == null) {
            throw new NullPointerException("sources == null");
        }

        if (exceptions == null) {
            throw new NullPointerException("exceptions == null");
        }

        if ((branchingness < BRANCH_MIN) || (branchingness > BRANCH_MAX)) {
            throw new IllegalArgumentException("bogus branchingness");
        }

        if ((exceptions.size() != 0) && (branchingness != BRANCH_THROW)) {
            throw new IllegalArgumentException("exceptions / branchingness " +
                                               "mismatch");
        }

        this.opcode = opcode;
        this.result = result;
        this.sources = sources;
        this.exceptions = exceptions;
        this.branchingness = branchingness;
        this.isCallLike = isCallLike;
        this.nickname = nickname;
    }

    /**
     * Constructs an instance. The constructed instance is never a 
     * call-like op (see {@link #isCallLike}).
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param result {@code non-null;} result type of this operation; {@link
     * Type#VOID} for no-result operations
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param exceptions {@code non-null;} list of possible types thrown by this
     * operation
     * @param branchingness the branchingness of this op; one of the
     * {@code BRANCH_*} constants
     * @param nickname {@code null-ok;} optional nickname (used for debugging)
     */
    public Rop(int opcode, Type result, TypeList sources,
               TypeList exceptions, int branchingness, String nickname) {
        this(opcode, result, sources, exceptions, branchingness, false,
             nickname);
    }

    /**
     * Constructs a no-exception instance. The constructed instance is never a 
     * call-like op (see {@link #isCallLike}).
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param result {@code non-null;} result type of this operation; {@link
     * Type#VOID} for no-result operations
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param branchingness the branchingness of this op; one of the
     * {@code BRANCH_*} constants
     * @param nickname {@code null-ok;} optional nickname (used for debugging)
     */
    public Rop(int opcode, Type result, TypeList sources, int branchingness,
               String nickname) {
        this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false,
             nickname);
    }

    /**
     * Constructs a non-branching no-exception instance. The
     * {@code branchingness} is always {@code BRANCH_NONE},
     * and it is never a call-like op (see {@link #isCallLike}).
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param result {@code non-null;} result type of this operation; {@link
     * Type#VOID} for no-result operations
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param nickname {@code null-ok;} optional nickname (used for debugging)
     */
    public Rop(int opcode, Type result, TypeList sources, String nickname) {
        this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE,
             false, nickname);
    }

    /**
     * Constructs a non-empty exceptions instance. Its
     * {@code branchingness} is always {@code BRANCH_THROW},
     * but it is never a call-like op (see {@link #isCallLike}).
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param result {@code non-null;} result type of this operation; {@link
     * Type#VOID} for no-result operations
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param exceptions {@code non-null;} list of possible types thrown by this
     * operation
     * @param nickname {@code null-ok;} optional nickname (used for debugging)
     */
    public Rop(int opcode, Type result, TypeList sources, TypeList exceptions,
               String nickname) {
        this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false,
             nickname);
    }

    /**
     * Constructs a non-nicknamed instance with non-empty exceptions, which
     * is always a call-like op (see {@link #isCallLike}). Its
     * {@code branchingness} is always {@code BRANCH_THROW}.
     * 
     * @param opcode the opcode; one of the constants in {@link RegOps}
     * @param sources {@code non-null;} types of all the sources of this operation
     * @param exceptions {@code non-null;} list of possible types thrown by this
     * operation
     */
    public Rop(int opcode, TypeList sources, TypeList exceptions) {
        this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true,
             null);
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object other) {
        if (this == other) {
            // Easy out.
            return true;
        }

        if (!(other instanceof Rop)) {
            return false;
        }

        Rop rop = (Rop) other;

        return (opcode == rop.opcode) &&
            (branchingness == rop.branchingness) &&
            (result == rop.result) &&
            sources.equals(rop.sources) &&
            exceptions.equals(rop.exceptions);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        int h = (opcode * 31) + branchingness;
        h = (h * 31) + result.hashCode();
        h = (h * 31) + sources.hashCode();
        h = (h * 31) + exceptions.hashCode();

        return h;
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer(40);

        sb.append("Rop{");

        sb.append(RegOps.opName(opcode));

        if (result != Type.VOID) {
            sb.append(" ");
            sb.append(result);
        } else {
            sb.append(" .");
        }

        sb.append(" <-");

        int sz = sources.size();
        if (sz == 0) {
            sb.append(" .");
        } else {
            for (int i = 0; i < sz; i++) {
                sb.append(' ');
                sb.append(sources.getType(i));
            }
        }

        if (isCallLike) {
            sb.append(" call");
        }

        sz = exceptions.size();
        if (sz != 0) {
            sb.append(" throws");
            for (int i = 0; i < sz; i++) {
                sb.append(' ');
                Type one = exceptions.getType(i);
                if (one == Type.THROWABLE) {
                    sb.append("<any>");
                } else {
                    sb.append(exceptions.getType(i));
                }
            }
        } else {
            switch (branchingness) {
                case BRANCH_NONE:   sb.append(" flows"); break;
                case BRANCH_RETURN: sb.append(" returns"); break;
                case BRANCH_GOTO:   sb.append(" gotos"); break;
                case BRANCH_IF:     sb.append(" ifs"); break;
                case BRANCH_SWITCH: sb.append(" switches"); break;
                default: sb.append(" " + Hex.u1(branchingness)); break;
            }
        }

        sb.append('}');

        return sb.toString();
    }

    /**
     * Gets the opcode.
     * 
     * @return the opcode
     */
    public int getOpcode() {
        return opcode;
    }

    /**
     * Gets the result type. A return value of {@link Type#VOID}
     * means this operation returns nothing.
     * 
     * @return {@code null-ok;} the result spec
     */
    public Type getResult() {
        return result;
    }

    /**
     * Gets the source types.
     * 
     * @return {@code non-null;} the source types
     */
    public TypeList getSources() {
        return sources;
    }

    /**
     * Gets the list of exception types that might be thrown.
     * 
     * @return {@code non-null;} the list of exception types
     */
    public TypeList getExceptions() {
        return exceptions;
    }

    /**
     * Gets the branchingness of this instance.
     * 
     * @return the branchingness
     */
    public int getBranchingness() {
        return branchingness;
    }

    /**
     * Gets whether this opcode is a function/method call or similar.
     * 
     * @return {@code true} iff this opcode is call-like
     */
    public boolean isCallLike() {
        return isCallLike;
    }


    /**
     * Gets whether this opcode is commutative (the order of its sources are
     * unimportant) or not. All commutative Rops have exactly two sources and
     * have no branchiness.
     *
     * @return true if rop is commutative
     */
    public boolean isCommutative() {
        switch (opcode) {
            case RegOps.AND:
            case RegOps.OR:
            case RegOps.XOR:
            case RegOps.ADD:
            case RegOps.MUL:
                return true;
            default:
                return false;
        }
    }

    /**
     * Gets the nickname. If this instance has no nickname, this returns
     * the result of calling {@link #toString}.
     * 
     * @return {@code non-null;} the nickname
     */
    public String getNickname() {
        if (nickname != null) {
            return nickname;
        }

        return toString();
    }

    /**
     * Gets whether this operation can possibly throw an exception. This
     * is just a convenient wrapper for
     * {@code getExceptions().size() != 0}.
     * 
     * @return {@code true} iff this operation can possibly throw
     */
    public final boolean canThrow() {
        return (exceptions.size() != 0);
    }
}
