/*
 * 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.ToHuman;

/**
 * A register-based instruction. An instruction is the combination of
 * an opcode (which specifies operation and source/result types), a
 * list of actual sources and result registers/values, and additional
 * information.
 */
public abstract class Insn implements ToHuman {
    /** {@code non-null;} opcode */
    private final Rop opcode;

    /** {@code non-null;} source position */
    private final SourcePosition position;

    /** {@code null-ok;} spec for the result of this instruction, if any */
    private final RegisterSpec result;

    /** {@code non-null;} specs for all the sources of this instruction */
    private final RegisterSpecList sources;

    /**
     * Constructs an instance.
     *
     * @param opcode {@code non-null;} the opcode
     * @param position {@code non-null;} source position
     * @param result {@code null-ok;} spec for the result, if any
     * @param sources {@code non-null;} specs for all the sources
     */
    public Insn(Rop opcode, SourcePosition position, RegisterSpec result,
                RegisterSpecList sources) {
        if (opcode == null) {
            throw new NullPointerException("opcode == null");
        }

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

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

        this.opcode = opcode;
        this.position = position;
        this.result = result;
        this.sources = sources;
    }

    /**
     * {@inheritDoc}
     *
     * Instances of this class compare by identity. That is,
     * {@code x.equals(y)} is only true if {@code x == y}.
     */
    @Override
    public final boolean equals(Object other) {
        return (this == other);
    }

    /**
     * {@inheritDoc}
     *
     * This implementation returns the identity hashcode of this
     * instance. This is proper, since instances of this class compare
     * by identity (see {@link #equals}).
     */
    @Override
    public final int hashCode() {
        return System.identityHashCode(this);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return toStringWithInline(getInlineString());
    }

    /**
     * Gets a human-oriented (and slightly lossy) string for this instance.
     *
     * @return {@code non-null;} the human string form
     */
    public String toHuman() {
        return toHumanWithInline(getInlineString());
    }

    /**
     * Gets an "inline" string portion for toHuman(), if available. This
     * is the portion that appears after the Rop opcode
     *
     * @return {@code null-ok;} if non-null, the inline text for toHuman()
     */
    public String getInlineString() {
        return null;
    }

    /**
     * Gets the opcode.
     *
     * @return {@code non-null;} the opcode
     */
    public final Rop getOpcode() {
        return opcode;
    }

    /**
     * Gets the source position.
     *
     * @return {@code non-null;} the source position
     */
    public final SourcePosition getPosition() {
        return position;
    }

    /**
     * Gets the result spec, if any. A return value of {@code null}
     * means this instruction returns nothing.
     *
     * @return {@code null-ok;} the result spec, if any
     */
    public final RegisterSpec getResult() {
        return result;
    }

    /**
     * Gets the spec of a local variable assignment that occurs at this
     * instruction, or null if no local variable assignment occurs. This
     * may be the result register, or for {@code mark-local} insns
     * it may be the source.
     *
     * @return {@code null-ok;} a named register spec or null
     */
    public final RegisterSpec getLocalAssignment() {
        RegisterSpec assignment;
        if (opcode.getOpcode() == RegOps.MARK_LOCAL) {
            assignment = sources.get(0);
        } else {
            assignment = result;
        }

        if (assignment == null) {
            return null;
        }

        LocalItem localItem = assignment.getLocalItem();

        if (localItem == null) {
            return null;
        }

        return assignment;
    }

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

    /**
     * Gets whether this instruction can possibly throw an exception. This
     * is just a convenient wrapper for {@code getOpcode().canThrow()}.
     *
     * @return {@code true} iff this instruction can possibly throw
     */
    public final boolean canThrow() {
        return opcode.canThrow();
    }

    /**
     * Gets the list of possibly-caught exceptions. This returns {@link
     * StdTypeList#EMPTY} if this instruction has no handlers,
     * which can be <i>either</i> if this instruction can't possibly
     * throw or if it merely doesn't handle any of its possible
     * exceptions. To determine whether this instruction can throw,
     * use {@link #canThrow}.
     *
     * @return {@code non-null;} the catches list
     */
    public abstract TypeList getCatches();

    /**
     * Calls the appropriate method on the given visitor, depending on the
     * class of this instance. Subclasses must override this.
     *
     * @param visitor {@code non-null;} the visitor to call on
     */
    public abstract void accept(Visitor visitor);

    /**
     * Returns an instance that is just like this one, except that it
     * has a catch list with the given item appended to the end. This
     * method throws an exception if this instance can't possibly
     * throw. To determine whether this instruction can throw, use
     * {@link #canThrow}.
     *
     * @param type {@code non-null;} type to append to the catch list
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract Insn withAddedCatch(Type type);

    /**
     * Returns an instance that is just like this one, except that all
     * register references have been offset by the given delta.
     *
     * @param delta the amount to offset register references by
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract Insn withRegisterOffset(int delta);

    /**
     * Returns an instance that is just like this one, except that, if
     * possible, the insn is converted into a version in which a source
     * (if it is a constant) is represented directly rather than as a
     * register reference. {@code this} is returned in cases where the
     * translation is not possible.
     *
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public Insn withSourceLiteral() {
        return this;
    }

    /**
     * Returns an exact copy of this Insn
     *
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public Insn copy() {
        return withRegisterOffset(0);
    }


    /**
     * Compares, handling nulls safely
     *
     * @param a first object
     * @param b second object
     * @return true if they're equal or both null.
     */
    private static boolean equalsHandleNulls (Object a, Object b) {
        return (a == b) || ((a != null) && a.equals(b));
    }

    /**
     * Compares Insn contents, since {@code Insn.equals()} is defined
     * to be an identity compare. Insn's are {@code contentEquals()}
     * if they have the same opcode, registers, source position, and other
     * metadata.
     *
     * @return true in the case described above
     */
    public boolean contentEquals(Insn b) {
        return opcode == b.getOpcode()
                && position.equals(b.getPosition())
                && (getClass() == b.getClass())
                && equalsHandleNulls(result, b.getResult())
                && equalsHandleNulls(sources, b.getSources())
                && StdTypeList.equalContents(getCatches(), b.getCatches());
    }

    /**
     * Returns an instance that is just like this one, except
     * with new result and source registers.
     *
     * @param result {@code null-ok;} new result register
     * @param sources {@code non-null;} new sources registers
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public abstract Insn withNewRegisters(RegisterSpec result,
            RegisterSpecList sources);

    /**
     * Returns the string form of this instance, with the given bit added in
     * the standard location for an inline argument.
     *
     * @param extra {@code null-ok;} the inline argument string
     * @return {@code non-null;} the string form
     */
    protected final String toStringWithInline(String extra) {
        StringBuffer sb = new StringBuffer(80);

        sb.append("Insn{");
        sb.append(position);
        sb.append(' ');
        sb.append(opcode);

        if (extra != null) {
            sb.append(' ');
            sb.append(extra);
        }

        sb.append(" :: ");

        if (result != null) {
            sb.append(result);
            sb.append(" <- ");
        }

        sb.append(sources);
        sb.append('}');

        return sb.toString();
    }

    /**
     * Returns the human string form of this instance, with the given
     * bit added in the standard location for an inline argument.
     *
     * @param extra {@code null-ok;} the inline argument string
     * @return {@code non-null;} the human string form
     */
    protected final String toHumanWithInline(String extra) {
        StringBuffer sb = new StringBuffer(80);

        sb.append(position);
        sb.append(": ");
        sb.append(opcode.getNickname());

        if (extra != null) {
            sb.append("(");
            sb.append(extra);
            sb.append(")");
        }

        if (result == null) {
            sb.append(" .");
        } else {
            sb.append(" ");
            sb.append(result.toHuman());
        }

        sb.append(" <-");

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

        return sb.toString();
    }


    /**
     * Visitor interface for this (outer) class.
     */
    public static interface Visitor {
        /**
         * Visits a {@link PlainInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitPlainInsn(PlainInsn insn);

        /**
         * Visits a {@link PlainCstInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitPlainCstInsn(PlainCstInsn insn);

        /**
         * Visits a {@link SwitchInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitSwitchInsn(SwitchInsn insn);

        /**
         * Visits a {@link ThrowingCstInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitThrowingCstInsn(ThrowingCstInsn insn);

        /**
         * Visits a {@link ThrowingInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitThrowingInsn(ThrowingInsn insn);

        /**
         * Visits a {@link FillArrayDataInsn}.
         *
         * @param insn {@code non-null;} the instruction to visit
         */
        public void visitFillArrayDataInsn(FillArrayDataInsn insn);
    }

    /**
     * Base implementation of {@link Visitor}, which has empty method
     * bodies for all methods.
     */
    public static class BaseVisitor implements Visitor {
        /** {@inheritDoc} */
        public void visitPlainInsn(PlainInsn insn) {
            // This space intentionally left blank.
        }

        /** {@inheritDoc} */
        public void visitPlainCstInsn(PlainCstInsn insn) {
            // This space intentionally left blank.
        }

        /** {@inheritDoc} */
        public void visitSwitchInsn(SwitchInsn insn) {
            // This space intentionally left blank.
        }

        /** {@inheritDoc} */
        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
            // This space intentionally left blank.
        }

        /** {@inheritDoc} */
        public void visitThrowingInsn(ThrowingInsn insn) {
            // This space intentionally left blank.
        }

        /** {@inheritDoc} */
        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
            // This space intentionally left blank.
        }
    }
}
