 
 extension WebSocketHeader {
     func serialize() -> [Byte] {
+        let zero = serializeByteZero()
+        let one = serializeByteZero()
         return []
     }
 

    case key(zero: UInt8, one: UInt8, two: UInt8, three: UInt8)
}

public struct WebSocketHeader {
    let fin: Bool


//    return str
//}

/*
 0               1               2               3
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+
 */
public final class MessageSerializer {
    private let message: WebSocketMessage

    private var bytes: [Byte] = []

    private init(_ message: WebSocketMessage) {
        self.message = message
    }

    func serializeByteZero() -> [Byte] {
        let header = message.header

        /*
         0 1 2 3 4 5 6 7
         f r r r o
         i s s s p
         n v v v
         1 2 3 c
         o
         d
         e
         */
        var byte: Byte = 0
        if header.fin {
            byte |= .fin
        }
        if header.rsv1 {
            byte |= .rsv1
        }
        if header.rsv2 {
            byte |= .rsv2
        }
        if header.rsv3 {
            byte |= .rsv3
        }

        let op = header.opCode.serialize() & .opCode
        byte |= op

        return [byte]
    }

    func serializeMaskAndLength() -> [Byte] {
        let header = message.header

        // first length byte is bit 0: mask, bit 1...7: length or indicator of additional bytes
        var primaryByte: Byte = 0
        if header.isMasked {
            primaryByte |= Byte.maskKeyIncluded
        }

        // 126 / 127 (max, max-1) indicate 2 & 8 byte extensions respectively
        if header.payloadLength < 126 {
            primaryByte |= UInt8(header.payloadLength)
            return [primaryByte] // lengths < 126 don't need additional bytes
        } else if header.payloadLength < UInt16.max.toUIntMax() {
            primaryByte |= 126 // 126 flags that 2 bytes are required
            let lengthBytes = UInt16(header.payloadLength).bytes()
            return [primaryByte] + lengthBytes
        } else {
            primaryByte |= 127 // 127 flags that 8 bytes are requred
            return [primaryByte] + header.payloadLength.bytes() // UInt64 == 8 bytes natively
        }
    }

    private func serializeMaskingKey() -> [Byte] {
        return message.header.maskingKey.serialize()
    }

    private func serializeHeader() -> [Byte] {
        let zero = serializeByteZero()
        let maskAndLength = serializeMaskAndLength()
        let maskingKey = serializeMaskingKey()
        fatalError()
    }

    private func serializePayload() -> [Byte] {
        fatalError()
//        switch message.header.maskingKey {
//        case .none:
//            return message.payload
//        case let .key(zero: zero, one: one, two: two, three: three):
//
//        }
    }

    private func serialize() -> [Byte] {
        let header = serializeHeader()
        fatalError()
    }
}

