/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.qpid.protonj2.test.driver;

import static org.hamcrest.CoreMatchers.isA;
import static org.hamcrest.CoreMatchers.notNullValue;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.UUID;

import org.apache.qpid.protonj2.test.driver.actions.AMQPHeaderInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.AttachInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.BeginInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.CloseInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.DeclareInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.DetachInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.DetachLastCoordinatorInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.DischargeInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.DispositionInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.EmptyFrameInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.EndInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.ExecuteUserCodeAction;
import org.apache.qpid.protonj2.test.driver.actions.FlowInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.OpenInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.RawBytesInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.SaslChallengeInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.SaslInitInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.SaslMechanismsInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.SaslOutcomeInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.SaslResponseInjectAction;
import org.apache.qpid.protonj2.test.driver.actions.TransferInjectAction;
import org.apache.qpid.protonj2.test.driver.codec.messaging.Source;
import org.apache.qpid.protonj2.test.driver.codec.messaging.Target;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger;
import org.apache.qpid.protonj2.test.driver.codec.security.SaslCode;
import org.apache.qpid.protonj2.test.driver.codec.transactions.Coordinator;
import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader;
import org.apache.qpid.protonj2.test.driver.codec.transport.Role;
import org.apache.qpid.protonj2.test.driver.expectations.AMQPHeaderExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.AttachExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.BeginExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.CloseExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.ConnectionDropExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.DeclareExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.DetachExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.DischargeExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.DispositionExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.EmptyFrameExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.EndExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.FlowExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.OpenExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.SaslChallengeExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.SaslInitExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.SaslMechanismsExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.SaslOutcomeExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.SaslResponseExpectation;
import org.apache.qpid.protonj2.test.driver.expectations.TransferExpectation;
import org.hamcrest.Matchers;

/**
 * Class used to create test scripts using the {@link AMQPTestDriver}
 */
public abstract class ScriptWriter {

    /**
     * Implemented in the subclass this method returns the active AMQP test driver
     * instance being used for the tests.
     *
     * @return the {@link AMQPTestDriver} to use for building a test script.
     */
    public abstract AMQPTestDriver getDriver();

    //----- AMQP Performative expectations

    public AMQPHeaderExpectation expectAMQPHeader() {
        final AMQPHeaderExpectation expecting = new AMQPHeaderExpectation(AMQPHeader.getAMQPHeader(), getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public OpenExpectation expectOpen() {
        final OpenExpectation expecting = new OpenExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public CloseExpectation expectClose() {
        final CloseExpectation expecting = new CloseExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public BeginExpectation expectBegin() {
        final BeginExpectation expecting = new BeginExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public EndExpectation expectEnd() {
        final EndExpectation expecting = new EndExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public AttachExpectation expectAttach() {
        final AttachExpectation expecting = new AttachExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public DetachExpectation expectDetach() {
        final DetachExpectation expecting = new DetachExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public FlowExpectation expectFlow() {
        final FlowExpectation expecting = new FlowExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public TransferExpectation expectTransfer() {
        final TransferExpectation expecting = new TransferExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public DispositionExpectation expectDisposition() {
        final DispositionExpectation expecting = new DispositionExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public EmptyFrameExpectation expectEmptyFrame() {
        final EmptyFrameExpectation expecting = new EmptyFrameExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public ConnectionDropExpectation expectConnectionToDrop() {
        final ConnectionDropExpectation expecting = new ConnectionDropExpectation();
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    //----- Transaction expectations

    public AttachExpectation expectCoordinatorAttach() {
        final AttachExpectation expecting = new AttachExpectation(getDriver());

        expecting.withRole(Role.SENDER);
        expecting.withCoordinator(isA(Coordinator.class));
        expecting.withSource(notNullValue());

        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public DeclareExpectation expectDeclare() {
        final DeclareExpectation expecting = new DeclareExpectation(getDriver());

        expecting.withHandle(notNullValue());
        expecting.withDeliveryId(notNullValue());
        expecting.withDeliveryTag(notNullValue());
        expecting.withMessageFormat(Matchers.oneOf(null, 0, UnsignedInteger.ZERO));

        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public DischargeExpectation expectDischarge() {
        final DischargeExpectation expecting = new DischargeExpectation(getDriver());

        expecting.withHandle(notNullValue());
        expecting.withDeliveryId(notNullValue());
        expecting.withDeliveryTag(notNullValue());
        expecting.withMessageFormat(Matchers.oneOf(null, 0, UnsignedInteger.ZERO));

        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    //----- SASL performative expectations

    public AMQPHeaderExpectation expectSASLHeader() {
        final AMQPHeaderExpectation expecting = new AMQPHeaderExpectation(AMQPHeader.getSASLHeader(), getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public SaslMechanismsExpectation expectSaslMechanisms() {
        final SaslMechanismsExpectation expecting = new SaslMechanismsExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public SaslInitExpectation expectSaslInit() {
        final SaslInitExpectation expecting = new SaslInitExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public SaslChallengeExpectation expectSaslChallenge() {
        final SaslChallengeExpectation expecting = new SaslChallengeExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public SaslResponseExpectation expectSaslResponse() {
        final SaslResponseExpectation expecting = new SaslResponseExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    public SaslOutcomeExpectation expectSaslOutcome() {
        final SaslOutcomeExpectation expecting = new SaslOutcomeExpectation(getDriver());
        getDriver().addScriptedElement(expecting);
        return expecting;
    }

    //----- Remote operations that happen while running the test script

    public AMQPHeaderInjectAction remoteHeader(byte[] header) {
        return new AMQPHeaderInjectAction(getDriver(), new AMQPHeader(header));
    }

    public AMQPHeaderInjectAction remoteHeader(AMQPHeader header) {
        return new AMQPHeaderInjectAction(getDriver(), header);
    }

    public AMQPHeaderInjectAction remoteAMQPHeader() {
        return new AMQPHeaderInjectAction(getDriver(), AMQPHeader.getAMQPHeader());
    }

    public AMQPHeaderInjectAction remoteSASLHeader() {
        return new AMQPHeaderInjectAction(getDriver(), AMQPHeader.getSASLHeader());
    }

    public OpenInjectAction remoteOpen() {
        return new OpenInjectAction(getDriver());
    }

    public CloseInjectAction remoteClose() {
        return new CloseInjectAction(getDriver());
    }

    public BeginInjectAction remoteBegin() {
        return new BeginInjectAction(getDriver());
    }

    public EndInjectAction remoteEnd() {
        return new EndInjectAction(getDriver());
    }

    public AttachInjectAction remoteAttach() {
        return new AttachInjectAction(getDriver());
    }

    public DetachInjectAction remoteDetach() {
        return new DetachInjectAction(getDriver());
    }

    public DetachInjectAction remoteDetachLastCoordinatorLink() {
        return new DetachLastCoordinatorInjectAction(getDriver());
    }

    public FlowInjectAction remoteFlow() {
        return new FlowInjectAction(getDriver());
    }

    public TransferInjectAction remoteTransfer() {
        return new TransferInjectAction(getDriver());
    }

    public DispositionInjectAction remoteDisposition() {
        return new DispositionInjectAction(getDriver());
    }

    public DeclareInjectAction remoteDeclare() {
        return new DeclareInjectAction(getDriver());
    }

    public DischargeInjectAction remoteDischarge() {
        return new DischargeInjectAction(getDriver());
    }

    public EmptyFrameInjectAction remoteEmptyFrame() {
        return new EmptyFrameInjectAction(getDriver());
    }

    public RawBytesInjectAction remoteBytes() {
        return new RawBytesInjectAction(getDriver());
    }

    //----- Remote SASL operations that can be scripted during tests

    public SaslInitInjectAction remoteSaslInit() {
        return new SaslInitInjectAction(getDriver());
    }

    public SaslMechanismsInjectAction remoteSaslMechanisms() {
        return new SaslMechanismsInjectAction(getDriver());
    }

    public SaslChallengeInjectAction remoteSaslChallenge() {
        return new SaslChallengeInjectAction(getDriver());
    }

    public SaslResponseInjectAction remoteSaslResponse() {
        return new SaslResponseInjectAction(getDriver());
    }

    public SaslOutcomeInjectAction remoteSaslOutcome() {
        return new SaslOutcomeInjectAction(getDriver());
    }

    //----- SASL related test expectations

    /**
     * Creates all the scripted elements needed for a successful SASL Anonymous
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises anonymous as the mechanism.  It is expected that the remote will
     * send a SASL init with the anonymous mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     */
    public void expectSASLAnonymousConnect() {
        expectSASLAnonymousConnect("ANONYMOUS");
    }

    /**
     * Creates all the scripted elements needed for a successful SASL Anonymous
     * connection. The provided set of mechanisms must contain the anonymous SASL
     * mechanism or an exception is thrown as otherwise the premise of this test
     * method could not be met. This is generally used with a server type peer
     * which will be accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises anonymous as the mechanism.  It is expected that the remote will
     * send a SASL init with the anonymous mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     *
     * @param mechanisms
     * 		The set of offered SASL mechanisms which must contain "ANONYMOUS"
     */
    public void expectSASLAnonymousConnect(String...mechanisms) {
        if (!Arrays.asList(mechanisms).contains("ANONYMOUS")) {
            throw new AssertionError("The list of mechanisms must contain ANONYMOUS for this expectation to be valid.");
        }

        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms(mechanisms).queue();
        expectSaslInit().withMechanism("ANONYMOUS");
        remoteSaslOutcome().withCode(SaslCode.OK).queue();
        expectAMQPHeader().respondWithAMQPHeader();
    }

    /**
     * Creates all the scripted elements needed for a successful SASL Plain
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises plain as the mechanism.  It is expected that the remote will
     * send a SASL init with the plain mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     *
     * @param username
     *      The user name that is expected in the SASL Plain initial response.
     * @param password
     *      The password that is expected in the SASL Plain initial response.
     */
    public void expectSASLPlainConnect(String username, String password) {
        expectSASLPlainConnect(username, password, "PLAIN");
    }

    /**
     * Creates all the scripted elements needed for a successful SASL Plain
     * connection. The provided set of mechanisms must contain the plain SASL
     * mechanism or an exception is thrown as otherwise the premise of this test
     * method could not be met. This is generally used with a server type peer
     * which will be accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises plain as the mechanism.  It is expected that the remote will
     * send a SASL init with the plain mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     *
     * @param username
     *      The user name that is expected in the SASL Plain initial response.
     * @param password
     *      The password that is expected in the SASL Plain initial response.
     * @param mechanisms
     * 		The set of offered SASL mechanisms which must contain "PLAIN"
     */
    public void expectSASLPlainConnect(String username, String password, String...mechanisms) {
        if (!Arrays.asList(mechanisms).contains("PLAIN")) {
            throw new AssertionError("The list of mechanisms must contain PLAIN for this expectation to be valid.");
        }

        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms(mechanisms).queue();
        expectSaslInit().withMechanism("PLAIN").withInitialResponse(saslPlainInitialResponse(username, password));
        remoteSaslOutcome().withCode(SaslCode.OK).queue();
        expectAMQPHeader().respondWithAMQPHeader();
    }

    /**
     * Creates all the scripted elements needed for a successful SASL XOAUTH2
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises XOAUTH2 as the mechanism.  It is expected that the remote will
     * send a SASL init with the XOAUTH2 mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     *
     * @param username
     *      The user name that is expected in the SASL initial response.
     * @param password
     *      The password that is expected in the SASL initial response.
     */
    public void expectSaslXOauth2Connect(String username, String password) {
        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms("XOAUTH2").queue();
        expectSaslInit().withMechanism("XOAUTH2").withInitialResponse(saslXOauth2InitialResponse(username, password));
        remoteSaslOutcome().withCode(SaslCode.OK).queue();
        expectAMQPHeader().respondWithAMQPHeader();
    }

    /**
     * Creates all the scripted elements needed for a failed SASL Plain
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises plain as the mechanism.  It is expected that the remote will
     * send a SASL init with the plain mechanism selected and the outcome is
     * predefined failing the exchange.
     *
     * @param saslCode
     *      The SASL code that indicates which failure the remote will be sent.
     */
    public void expectFailingSASLPlainConnect(byte saslCode) {
        expectFailingSASLPlainConnect(saslCode, "PLAIN");
    }

    /**
     * Creates all the scripted elements needed for a failed SASL Plain
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises plain as the mechanism.  It is expected that the remote will
     * send a SASL init with the plain mechanism selected and the outcome is
     * predefined failing the exchange.
     *
     * @param saslCode
     *      The SASL code that indicates which failure the remote will be sent.
     * @param offeredMechanisms
     *      The set of mechanisms that the server should offer in the SASL Mechanisms frame
     */
    public void expectFailingSASLPlainConnect(byte saslCode, String...offeredMechanisms) {
        if (!Arrays.asList(offeredMechanisms).contains("PLAIN")) {
            throw new AssertionError("Expected offered mechanisms that contains the PLAIN mechanism");
        }

        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms(offeredMechanisms).queue();
        expectSaslInit().withMechanism("PLAIN");

        if (saslCode <= 0 || saslCode > SaslCode.SYS_TEMP.ordinal()) {
            throw new IllegalArgumentException("SASL Code should indicate a failure");
        }

        remoteSaslOutcome().withCode(SaslCode.valueOf(saslCode)).queue();
    }

    /**
     * Creates all the scripted elements needed for a successful SASL EXTERNAL
     * connection. This is generally used with a server type peer which will be
     * accepting client connections.
     * <p>
     * For this exchange the SASL header is expected which is responded to with the
     * corresponding SASL header and an immediate SASL mechanisms frame that only
     * advertises EXTERNAL as the mechanism.  It is expected that the remote will
     * send a SASL init with the EXTERNAL mechanism selected and the outcome is
     * predefined as success.  Once done the expectation is added for the AMQP
     * header to arrive and a header response will be sent.
     */
    public void expectSaslExternalConnect() {
        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms("EXTERNAL").queue();
        expectSaslInit().withMechanism("EXTERNAL").withInitialResponse(new byte[0]);
        remoteSaslOutcome().withCode(SaslCode.OK).queue();
        expectAMQPHeader().respondWithAMQPHeader();
    }

    /**
     * Creates all the scripted elements needed for a SASL exchange with the offered
     * mechanisms but the client should fail if configured such that it cannot match
     * any of those to its own available mechanisms.
     *
     * @param offeredMechanisms
     *      The set of SASL Mechanisms to advertise as available on the peer.
     */
    public void expectSaslMechanismNegotiationFailure(String... offeredMechanisms) {
        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms(offeredMechanisms).queue();
    }

    /**
     * Creates all the scripted elements needed for a SASL exchange with the offered
     * mechanisms with the expectation that the client will respond with the provided
     * mechanism and then the server will fail the exchange with the auth failed code.
     *
     * @param offeredMechanisms
     *      The set of SASL Mechanisms to advertise as available on the peer.
     * @param chosenMechanism
     *      The SASL Mechanism that the client should select and respond with.
     */
    public void expectSaslConnectThatAlwaysFailsAuthentication(String[] offeredMechanisms, String chosenMechanism) {
        expectSASLHeader().respondWithSASLHeader();
        remoteSaslMechanisms().withMechanisms(offeredMechanisms).queue();
        expectSaslInit().withMechanism(chosenMechanism);
        remoteSaslOutcome().withCode(SaslCode.AUTH).queue();
    }

    /**
     * Used to queue the sequence of frames that would occur during a typical client
     * connection to a remote peer with SASL anonymous. This should be called before a
     * client connect attempt as the queued headers won't fire if queued after the
     * connection has already been established.
     */
    public void queueClientSaslAnonymousConnect() {
        remoteSASLHeader().queue();
        expectSASLHeader();
        expectSaslMechanisms().withSaslServerMechanism("ANONYMOUS");
        remoteSaslInit().withMechanism("ANONYMOUS").queue();
        expectSaslOutcome().withCode(SaslCode.OK);
        remoteAMQPHeader().queue();
        expectAMQPHeader();
    }

    /**
     * Used to trigger the sequence of frames that would occur during a typical client
     * connection to a remote peer with SASL anonymous. This should be called after a
     * client connects to the remote as the fired frames would fail until there is a
     * connection in place.
     */
    public void triggerClientSaslAnonymousConnect() {
        expectSASLHeader();
        expectSaslMechanisms().withSaslServerMechanism("ANONYMOUS");
        remoteSaslInit().withMechanism("ANONYMOUS").queue();
        expectSaslOutcome().withCode(SaslCode.OK);
        remoteAMQPHeader().queue();

        // This trigger the exchange of frames.
        remoteSASLHeader().now();
    }

    /**
     * Used to queue the sequence of frames that would occur during a typical client
     * connection to a remote peer with SASL plain. This should be called before a
     * client connect attempt as the queued headers won't fire if queued after the
     * connection has already been established.
     *
     * @param username
     *      The user name that is expected in the SASL Plain initial response.
     * @param password
     *      The password that is expected in the SASL Plain initial response.
     */
    public void queueClientSaslPlainConnect(String username, String password) {
        remoteSASLHeader().queue();
        expectSASLHeader();
        expectSaslMechanisms().withSaslServerMechanism("PLAIN");
        remoteSaslInit().withMechanism("PLAIN").withInitialResponse(saslPlainInitialResponse(username, password)).queue();
        expectSaslOutcome().withCode(SaslCode.OK);
        remoteAMQPHeader().queue();
    }

    /**
     * Used to trigger the sequence of frames that would occur during a typical client
     * connection to a remote peer with SASL plain. This should be called after a
     * client connects to the remote as the fired frames would fail until there is a
     * connection in place.
     *
     * @param username
     *      The user name that is expected in the SASL Plain initial response.
     * @param password
     *      The password that is expected in the SASL Plain initial response.
     */
    public void triggerClientSaslPlainConnect(String username, String password) {
        expectSASLHeader();
        expectSaslMechanisms().withSaslServerMechanism("PLAIN");
        remoteSaslInit().withMechanism("PLAIN").withInitialResponse(saslPlainInitialResponse(username, password)).queue();
        expectSaslOutcome().withCode(SaslCode.OK);
        remoteAMQPHeader().queue();

        // This trigger the exchange of frames.
        remoteSASLHeader().now();
    }

    //----- Utility methods for tests writing raw scripted SASL tests

    public byte[] saslPlainInitialResponse(String username, String password) {
        final byte[] usernameBytes = username.getBytes(StandardCharsets.UTF_8);
        final byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
        final byte[] initialResponse = new byte[usernameBytes.length+passwordBytes.length+2];
        System.arraycopy(usernameBytes, 0, initialResponse, 1, usernameBytes.length);
        System.arraycopy(passwordBytes, 0, initialResponse, 2 + usernameBytes.length, passwordBytes.length);

        return initialResponse;
    }

    public byte[] saslXOauth2InitialResponse(String username, String password) {
        final byte[] usernameBytes = username.getBytes(StandardCharsets.UTF_8);
        final byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
        final byte[] initialResponse = new byte[usernameBytes.length+passwordBytes.length+20];

        System.arraycopy("user=".getBytes(StandardCharsets.US_ASCII), 0, initialResponse, 0, 5);
        System.arraycopy(usernameBytes, 0, initialResponse, 5, usernameBytes.length);
        initialResponse[5 + usernameBytes.length] = 1;
        System.arraycopy("auth=Bearer ".getBytes(StandardCharsets.US_ASCII), 0, initialResponse, 6+usernameBytes.length, 12);
        System.arraycopy(passwordBytes, 0, initialResponse, 18 + usernameBytes.length, passwordBytes.length);
        initialResponse[initialResponse.length - 2] = 1;
        initialResponse[initialResponse.length - 1] = 1;

        return initialResponse;
    }

    //----- Smart Scripted Response Actions

    /**
     * Creates a Begin response for the last session Begin that was received and fills in the Begin
     * fields based on values from the remote.  The caller can further customize the Begin that is
     * emitted by using the various with methods to assign values to the fields in the Begin.
     *
     * @return a new {@link BeginInjectAction} that can be queued or sent immediately.
     *
     * @throws IllegalStateException if no Begin has yet been received from the remote.
     */
    public BeginInjectAction respondToLastBegin() {
        final BeginInjectAction response = new BeginInjectAction(getDriver());

        final SessionTracker session = getDriver().sessions().getLastRemotelyOpenedSession();
        if (session == null) {
            throw new IllegalStateException("Cannot create response to Begin before one has been received.");
        }

        // Populate the response using data in the locally opened session, script can override this after return.
        response.withRemoteChannel(session.getRemoteChannel());

        return response;
    }

    /**
     * Creates a Attach response for the last link Attach that was received and fills in the Attach
     * fields based on values from the remote.  The caller can further customize the Attach that is
     * emitted by using the various with methods to assign values to the fields in the Attach.
     *
     * @return a new {@link AttachInjectAction} that can be queued or sent immediately.
     *
     * @throws IllegalStateException if no Attach has yet been received from the remote.
     */
    public AttachInjectAction respondToLastAttach() {
        final AttachInjectAction response = new AttachInjectAction(getDriver());
        final SessionTracker session = getDriver().sessions().getLastRemotelyOpenedSession();
        final LinkTracker link = session.getLastRemotelyOpenedLink();

        if (link == null) {
            throw new IllegalStateException("Cannot create response to Attach before one has been received.");
        }

        if (link.isLocallyAttached()) {
            throw new IllegalStateException("Cannot create response to Attach since a local Attach was already sent.");
        }

        // Populate the response using data in the locally opened link, script can override this after return.
        response.onChannel(link.getSession().getLocalChannel());
        response.withName(link.getName());
        response.withRole(link.getRole());
        response.withSndSettleMode(link.getRemoteSenderSettleMode());
        response.withRcvSettleMode(link.getRemoteReceiverSettleMode());

        if (link.getRemoteSource() != null) {
            response.withSource(new Source(link.getRemoteSource()));
            if (Boolean.TRUE.equals(link.getRemoteSource().getDynamic())) {
                response.withSource().withAddress(UUID.randomUUID().toString());
            }
        }
        if (link.getRemoteTarget() != null) {
            response.withTarget(new Target(link.getRemoteTarget()));
            if (Boolean.TRUE.equals(link.getRemoteTarget().getDynamic())) {
                response.withTarget().withAddress(UUID.randomUUID().toString());
            }
        }
        if (link.getRemoteCoordinator() != null) {
            response.withTarget(new Coordinator(link.getRemoteCoordinator()));
        }

        if (response.getPerformative().getInitialDeliveryCount() == null) {
            if (link.isSender()) {
                response.withInitialDeliveryCount(0);
            }
        }

        return response;
    }

    //----- Out of band script actions for user code

    /**
     * Allows for a user defined bit of code to be executed during the test script
     * in response to some incoming frame or as scripted after a given delay etc.
     * The action will be performed on the event thread of the peer outside the
     * thread that the tests run in.
     *
     * @param action
     * 		The {@link Runnable} action to be performed.
     *
     * @return the action instance which can either be queued or triggered immediately.
     */
    public ExecuteUserCodeAction execute(Runnable action) {
        return new ExecuteUserCodeAction(getDriver(), action);
    }

    //----- Immediate operations performed outside the test script

    public void fire(AMQPHeader header) {
        getDriver().sendHeader(header);
    }

    public void fireAMQP(DescribedType performative) {
        getDriver().sendAMQPFrame(0, performative, null);
    }

    public void fireSASL(DescribedType performative) {
        getDriver().sendSaslFrame(0, performative);
    }
}
