// Copyright 2017 Google Inc. 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 = make_scoped_refptr(
        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
