// Path: ws/src/main/java/org/kaazing/netx/ws/internal/ext/flyweight/Opcode.java
// public enum Opcode {
//     BINARY, CLOSE, CONTINUATION, PING, PONG, TEXT;
// 
//     public static Opcode fromInt(int value) {
//         switch (value) {
//         case 0x00:
//             return CONTINUATION;
//         case 0x01:
//             return TEXT;
//         case 0x02:
//             return BINARY;
//         case 0x08:
//             return CLOSE;
//         case 0x09:
//             return PING;
//         case 0x0A:
//             return PONG;
//         default:
//             throw new IllegalStateException(format("Unrecognized WebSocket OpCode %x", value));
//         }
//     };
// 
//     public static int toInt(Opcode value) {
//         switch (value) {
//         case CONTINUATION:
//             return 0x00;
//         case TEXT:
//             return 0x01;
//         case BINARY:
//             return 0x02;
//         case CLOSE:
//             return 0x08;
//         case PING:
//             return 0x09;
//         case PONG:
//             return 0x0A;
//         default:
//             throw new IllegalStateException(format("Unrecognised OpCode %s", value));
//         }
//     };
// }


import static java.lang.String.format;
import static java.util.EnumSet.allOf;
import static org.kaazing.netx.ws.internal.WebSocketState.CLOSED;
import static org.kaazing.netx.ws.internal.WebSocketState.OPEN;
import static org.kaazing.netx.ws.internal.WebSocketTransition.ERROR;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_BINARY_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_CLOSE_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_CONTINUATION_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_PONG_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_TEXT_FRAME;
import java.io.IOException;
import org.kaazing.netx.ws.internal.ext.flyweight.Frame;
import org.kaazing.netx.ws.internal.ext.flyweight.Opcode;
/**
 * Copyright 2007-2015, Kaazing Corporation. All rights reserved.
 *
 * 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 org.kaazing.netx.ws.internal;




public final class WebSocketOutputStateMachine {
    private static final WebSocketState[][] STATE_MACHINE;

    static {
        int stateCount = WebSocketState.values().length;
        int transitionCount = WebSocketTransition.values().length;

        WebSocketState[][] stateMachine = new WebSocketState[stateCount][transitionCount];
        for (WebSocketState state : allOf(WebSocketState.class)) {
            for (WebSocketTransition transition : allOf(WebSocketTransition.class)) {
                stateMachine[state.ordinal()][transition.ordinal()] = CLOSED;
            }

            stateMachine[state.ordinal()][ERROR.ordinal()] = CLOSED;
        }

        stateMachine[OPEN.ordinal()][SEND_PONG_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_CLOSE_FRAME.ordinal()] = CLOSED;
        stateMachine[OPEN.ordinal()][SEND_BINARY_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_CONTINUATION_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_TEXT_FRAME.ordinal()] = OPEN;

        STATE_MACHINE = stateMachine;
    }

    public WebSocketOutputStateMachine() {
    }

    public void start(WsURLConnectionImpl connection) {
        connection.setOutputState(WebSocketState.START);
    }

    public void processFrame(final WsURLConnectionImpl connection, final Frame frame) throws IOException {
        try {
            connection.getWriteLock().lock();

            DefaultWebSocketContext context = connection.getOutgoingContext();
            WebSocketState state = connection.getOutputState();
// Path: ws/src/main/java/org/kaazing/netx/ws/internal/ext/flyweight/Opcode.java
// public enum Opcode {
//     BINARY, CLOSE, CONTINUATION, PING, PONG, TEXT;
// 
//     public static Opcode fromInt(int value) {
//         switch (value) {
//         case 0x00:
//             return CONTINUATION;
//         case 0x01:
//             return TEXT;
//         case 0x02:
//             return BINARY;
//         case 0x08:
//             return CLOSE;
//         case 0x09:
//             return PING;
//         case 0x0A:
//             return PONG;
//         default:
//             throw new IllegalStateException(format("Unrecognized WebSocket OpCode %x", value));
//         }
//     };
// 
//     public static int toInt(Opcode value) {
//         switch (value) {
//         case CONTINUATION:
//             return 0x00;
//         case TEXT:
//             return 0x01;
//         case BINARY:
//             return 0x02;
//         case CLOSE:
//             return 0x08;
//         case PING:
//             return 0x09;
//         case PONG:
//             return 0x0A;
//         default:
//             throw new IllegalStateException(format("Unrecognised OpCode %s", value));
//         }
//     };
// }


// Path: ws/src/main/java/org/kaazing/netx/ws/internal/WebSocketOutputStateMachine.java
import static java.lang.String.format;
import static java.util.EnumSet.allOf;
import static org.kaazing.netx.ws.internal.WebSocketState.CLOSED;
import static org.kaazing.netx.ws.internal.WebSocketState.OPEN;
import static org.kaazing.netx.ws.internal.WebSocketTransition.ERROR;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_BINARY_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_CLOSE_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_CONTINUATION_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_PONG_FRAME;
import static org.kaazing.netx.ws.internal.WebSocketTransition.SEND_TEXT_FRAME;
import java.io.IOException;
import org.kaazing.netx.ws.internal.ext.flyweight.Frame;
import org.kaazing.netx.ws.internal.ext.flyweight.Opcode;

/**
 * Copyright 2007-2015, Kaazing Corporation. All rights reserved.
 *
 * 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 org.kaazing.netx.ws.internal;




public final class WebSocketOutputStateMachine {
    private static final WebSocketState[][] STATE_MACHINE;

    static {
        int stateCount = WebSocketState.values().length;
        int transitionCount = WebSocketTransition.values().length;

        WebSocketState[][] stateMachine = new WebSocketState[stateCount][transitionCount];
        for (WebSocketState state : allOf(WebSocketState.class)) {
            for (WebSocketTransition transition : allOf(WebSocketTransition.class)) {
                stateMachine[state.ordinal()][transition.ordinal()] = CLOSED;
            }

            stateMachine[state.ordinal()][ERROR.ordinal()] = CLOSED;
        }

        stateMachine[OPEN.ordinal()][SEND_PONG_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_CLOSE_FRAME.ordinal()] = CLOSED;
        stateMachine[OPEN.ordinal()][SEND_BINARY_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_CONTINUATION_FRAME.ordinal()] = OPEN;
        stateMachine[OPEN.ordinal()][SEND_TEXT_FRAME.ordinal()] = OPEN;

        STATE_MACHINE = stateMachine;
    }

    public WebSocketOutputStateMachine() {
    }

    public void start(WsURLConnectionImpl connection) {
        connection.setOutputState(WebSocketState.START);
    }

    public void processFrame(final WsURLConnectionImpl connection, final Frame frame) throws IOException {
        try {
            connection.getWriteLock().lock();

            DefaultWebSocketContext context = connection.getOutgoingContext();
            WebSocketState state = connection.getOutputState();
            Opcode opcode = frame.opcode();