package net.alphadev.usbstorage.bbb;

import static net.alphadev.usbstorage.util.BitStitching.convertToInt;

/**
 * @author Jan Seeger <jan@alphadev.net>
 */
public class CommandStatusWrapper {
    private byte[] mSignature;
    private int mTag;
    private int mDataResidue;
    private byte mStatus;

    public CommandStatusWrapper(byte[] data) {
        if (data.length != 13) {
            throw new IllegalArgumentException("CSW always has a length of 13 bytes!");
        }

        mSignature = new byte[4];
        mSignature[0x0] = data[0x0];
        mSignature[0x1] = data[0x1];
        mSignature[0x2] = data[0x2];
        mSignature[0x3] = data[0x3];

        mTag = convertToInt(data, 0x4);
        mDataResidue = convertToInt(data, 0x8);
        mStatus = data[0xc];
    }

    public String getSignature() {
        return new String(mSignature);
    }

    public int getTag() {
        return mTag;
    }

    public int getDataResidue() {
        return mDataResidue;
    }

    public Status getStatus() {
        switch (mStatus) {
            case 0:
                return Status.COMMAND_PASSED;
            case 2:
                return Status.CHECK_CONDITION;
            case 4:
                return Status.CONDITION_MET;
            case 8:
                return Status.BUSY;
            case 16:
                return Status.INTERMEDIATE;
            case 20:
                return Status.INTERMEDIATE_CONDITION_MET;
            case 34:
                return Status.COMMAND_TERMINATED;
            case 40:
                return Status.QUEUE_FULL;
            default:
                return Status.RESERVED;
        }
    }

    public static enum Status {
        /**
         * This status indicates that the target has successfully completed the command.
         */
        COMMAND_PASSED,

        /**
         * This status indicates that a contingent allegiance condition has occurred.
         */
        CHECK_CONDITION,
        CONDITION_MET,
        BUSY,
        INTERMEDIATE,
        INTERMEDIATE_CONDITION_MET,
        COMMAND_TERMINATED,
        QUEUE_FULL,
        RESERVED
    }
}

@@ -1437,32 +1437,105 @@
 _CONDITION_MET;%0A
+            case 24:%0A                return Status.RESERVATION_CONFLICT;%0A
             case
@@ -2039,30 +2039,581 @@
 ON,%0A
-        CONDITION_MET,
+%0A        /**%0A         * This status or INTERMEDIATE-CONDITION MET is returned whenever the requested operation is%0A         * satisfied (see the SEARCH DATA and PRE-FETCH commands).%0A         */%0A        CONDITION_MET,%0A%0A        /**%0A         * This status indicates that the target is busy.  This status shall be returned whenever a%0A         * target is unable to accept a command from an otherwise acceptable initiator (i.e., no%0A         * reservation conflicts).  The recommended initiator recovery action is to issue the%0A         * command again at a later time.%0A         */
 %0A   
@@ -2623,24 +2623,25 @@
   BUSY,%0A
+%0A
         
 INTERMED
@@ -2636,105 +2636,1826 @@
     
-INTERMEDIATE,%0A        INTERMEDIATE_CONDITION_MET,%0A        COMMAND_TERMINATED,%0A        QUEUE_FULL,
+/**%0A         * This status or INTERMEDIATE-CONDITION MET shall be returned for every successfully%0A         * completed command in a series of linked commands (except the last command), unless the%0A         * command is terminated with CHECK CONDITION, RESERVATION CONFLICT, or COMMAND TERMINATED%0A         * status.  If INTERMEDIATE or INTERMEDIATE-CONDITION MET status is not returned, the series%0A         * of linked commands is terminated and the I/O process is ended.%0A         */%0A        INTERMEDIATE,%0A%0A        /**%0A         * This status is the combination of the CONDITION MET and INTERMEDIATE statuses.%0A         */%0A        INTERMEDIATE_CONDITION_MET,%0A%0A        /**%0A         * This status shall be returned whenever an initiator attempts to access a logical unit or%0A         * an extent within a logical unit that is reserved with a conflicting reservation type for%0A         * another SCSI device (see the RESERVE and RESERVE UNIT commands).  The recommended%0A         * initiator recovery action is to issue the command again at a later time.%0A         */%0A        RESERVATION_CONFLICT,%0A%0A        /**%0A         * This status shall be returned whenever the target terminates the current I/O process%0A         * after receiving a TERMINATE I/O PROCESS message (see 5.6.22). This status also indicates%0A         * that a contingent allegiance condition has occurred (see 6.6).%0A         */%0A        COMMAND_TERMINATED,%0A%0A        /**%0A         * This status shall be implemented if tagged queuing is implemented. This status is%0A         * returned when a SIMPLE QUEUE TAG, ORDERED QUEUE TAG, or HEAD OF QUEUE TAG message is%0A         * received and the command queue is full. The I/O process is not placed in the command%0A         * queue.%0A         */%0A        QUEUE_FULL,%0A%0A        /**%0A         * Reserved for future use.%0A         */
 %0A   

add forgetten status flag. completed csw status documentation.