 //    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()
     }
 }
 


extension WebSocketHeader {
    func serialize() -> [Byte] {
        return []
    }


     |K|             |
     +-+-------------+
     */
    private func serializeMaskAndLength() -> (byte: Byte, extended: ExtendedPayloadByteLength?) {
        var byte: Byte = 0
        if isMasked {
            byte |= Byte.maskKeyIncluded
        }

        // 126 / 127 (max, max-1) indicate 2 & 8 byte extensions respectively
        if payloadLength < 126 {
            byte |= UInt8(payloadLength)
            return (byte, nil)
        } else if payloadLength < UInt16.max.toUIntMax() {
            byte |= 126 // 126 flags that 2 bytes are required
            return (byte, .two)
        } else {
            byte |= 127 // 127 flags that 8 bytes are requred
            return (byte, .eight)
        }
    }
}

