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

import com.android.dx.rop.code.RegisterSpecList;
import com.android.dx.rop.code.SourcePosition;

/**
 * Instruction which has a single branch target.
 */
public final class TargetInsn extends FixedSizeInsn {
    /** {@code non-null;} the branch target */
    private CodeAddress target;

    /**
     * Constructs an instance. The output address of this instance is initially
     * unknown ({@code -1}), and the target is initially
     * {@code null}.
     *
     * @param opcode the opcode; one of the constants from {@link Dops}
     * @param position {@code non-null;} source position
     * @param registers {@code non-null;} register list, including a
     * result register if appropriate (that is, registers may be either
     * ins or outs)
     * @param target {@code non-null;} the branch target
     */
    public TargetInsn(Dop opcode, SourcePosition position,
                      RegisterSpecList registers, CodeAddress target) {
        super(opcode, position, registers);

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

        this.target = target;
    }

    /** {@inheritDoc} */
    @Override
    public DalvInsn withOpcode(Dop opcode) {
        return new TargetInsn(opcode, getPosition(), getRegisters(), target);
    }

    /** {@inheritDoc} */
    @Override
    public DalvInsn withRegisters(RegisterSpecList registers) {
        return new TargetInsn(getOpcode(), getPosition(), registers, target);
    }

    /**
     * Returns an instance that is just like this one, except that its
     * opcode has the opposite sense (as a test; e.g. a
     * {@code lt} test becomes a {@code ge}), and its branch
     * target is replaced by the one given, and all set-once values
     * associated with the class (such as its address) are reset.
     *
     * @param target {@code non-null;} the new branch target
     * @return {@code non-null;} an appropriately-constructed instance
     */
    public TargetInsn withNewTargetAndReversed(CodeAddress target) {
        Dop opcode = getOpcode().getOppositeTest();

        return new TargetInsn(opcode, getPosition(), getRegisters(), target);
    }

    /**
     * Gets the unique branch target of this instruction.
     *
     * @return {@code non-null;} the branch target
     */
    public CodeAddress getTarget() {
        return target;
    }

    /**
     * Gets the target address of this instruction. This is only valid
     * to call if the target instruction has been assigned an address,
     * and it is merely a convenient shorthand for
     * {@code getTarget().getAddress()}.
     *
     * @return {@code >= 0;} the target address
     */
    public int getTargetAddress() {
        return target.getAddress();
    }

    /**
     * Gets the branch offset of this instruction. This is only valid to
     * call if both this and the target instruction each has been assigned
     * an address, and it is merely a convenient shorthand for
     * {@code getTargetAddress() - getAddress()}.
     *
     * @return the branch offset
     */
    public int getTargetOffset() {
        return target.getAddress() - getAddress();
    }

    /**
     * Returns whether the target offset is known.
     *
     * @return {@code true} if the target offset is known or
     * {@code false} if not
     */
    public boolean hasTargetOffset() {
        return hasAddress() && target.hasAddress();
    }

    /** {@inheritDoc} */
    @Override
    protected String argString() {
        if (target == null) {
            return "????";
        }

        return target.identifierString();
    }
}
