/**
   * Encode a simple UA TCP message.
   *
   * @param messageType {@link MessageType#Hello}, {@link MessageType#Acknowledge}, or {@link
   *     MessageType#Error}.
   * @param messageEncoder a function that encodes the message payload.
   * @param buffer the {@link ByteBuf} to encode into.
   */
  private static ByteBuf encode(
      MessageType messageType, Consumer<ByteBuf> messageEncoder, ByteBuf buffer)
      throws UaException {
    buffer.writeMedium(MessageType.toMediumInt(messageType));
    buffer.writeByte('F');

    int lengthIndex = buffer.writerIndex();
    buffer.writeInt(0);

    int indexBefore = buffer.writerIndex();
    messageEncoder.accept(buffer);
    int indexAfter = buffer.writerIndex();
    int bytesWritten = indexAfter - indexBefore;

    buffer.writerIndex(lengthIndex);
    buffer.writeInt(8 + bytesWritten);
    buffer.writerIndex(indexAfter);

    return buffer;
  }