// Copyright 2017 The Cobalt Authors. 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.

#include "cobalt/websocket/web_socket_message_container.h"

#include "base/basictypes.h"

namespace cobalt {
namespace websocket {

std::size_t CombineFramesChunks(WebSocketFrameContainer::const_iterator begin,
                                WebSocketFrameContainer::const_iterator end,
                                char *out_destination,
                                std::size_t buffer_length) {
  DCHECK(out_destination);
  std::size_t bytes_written = 0;
  std::size_t bytes_available = buffer_length;
  for (WebSocketFrameContainer::const_iterator iterator = begin;
       iterator != end; ++iterator) {
    const scoped_refptr<net::IOBufferWithSize> &data((*iterator)->data);

    if (data) {
      std::size_t frame_chunk_size = data->size();

      if (bytes_available >= frame_chunk_size) {
        SbMemoryCopy(out_destination, data->data(), frame_chunk_size);
        out_destination += frame_chunk_size;
        bytes_written += frame_chunk_size;
        bytes_available -= frame_chunk_size;
      }
    }
  }

  DCHECK_LE(bytes_written, buffer_length);
  return bytes_written;
}

bool WebSocketMessageContainer::Take(WebSocketFrameContainer *frame_container) {
  DCHECK(frame_container);
  DCHECK(!IsMessageComplete());
  DCHECK(frame_container->IsFrameComplete());
  if (!frame_container) {
    return false;
  }
  if (frame_container->empty()) {
    return true;
  }

  bool is_first_frame = frames_.empty();
  bool is_continuation_frame = frame_container->IsContinuationFrame();

  if (is_first_frame) {
    if (is_continuation_frame) {
      return false;
    }
  } else {
    // All frames after the first one must be continuation frames.
    if (!is_continuation_frame) {
      return false;
    }
  }

  frames_.push_back(WebSocketFrameContainer());

  WebSocketFrameContainer &last_object(frames_.back());
  last_object.swap(*frame_container);
  DCHECK(last_object.IsFrameComplete());

  payload_size_bytes_ += last_object.GetCurrentPayloadSizeBytes();
  message_completed_ |= last_object.IsFinalFrame();

  return true;
}

scoped_refptr<net::IOBufferWithSize>
WebSocketMessageContainer::GetMessageAsIOBuffer() const {
  scoped_refptr<net::IOBufferWithSize> buf;

  DCHECK_LE(kMaxMessagePayloadInBytes, static_cast<std::size_t>(kint32max));
  DCHECK_LE(payload_size_bytes_, kMaxMessagePayloadInBytes);
  DCHECK_GE(payload_size_bytes_, 0UL);

  if ((payload_size_bytes_ > 0) &&
      (payload_size_bytes_ <= kMaxMessagePayloadInBytes)) {
    buf = base::WrapRefCounted(
        new net::IOBufferWithSize(static_cast<int>(payload_size_bytes_)));

    std::size_t total_bytes_written = 0;

    char *data_pointer = buf->data();
    std::size_t size_remaining = buf->size();

    for (WebSocketFrames::const_iterator iterator = frames_.begin();
         iterator != frames_.end(); ++iterator) {
      const WebSocketFrameContainer &frame_container(*iterator);

      std::size_t bytes_written =
          CombineFramesChunks(frame_container.begin(), frame_container.end(),
                              data_pointer, size_remaining);

      DCHECK_LE(bytes_written, size_remaining);

      size_remaining -= bytes_written;
      data_pointer += bytes_written;

      total_bytes_written += bytes_written;
    }

    DCHECK_EQ(total_bytes_written, payload_size_bytes_);
  }

  return buf;
}

}  // namespace websocket
}  // namespace cobalt
