// 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.
#ifndef COBALT_WEBSOCKET_WEB_SOCKET_FRAME_CONTAINER_H_
#define COBALT_WEBSOCKET_WEB_SOCKET_FRAME_CONTAINER_H_

#include <algorithm>
#include <deque>
#include <memory>
#include <utility>

#include "base/basictypes.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_frame.h"

namespace cobalt {
namespace websocket {

const size_t kMaxFramePayloadInBytes = 4 * 1024 * 1024;

class WebSocketFrameContainer {
 public:
  typedef std::deque<const net::WebSocketFrameChunk*> WebSocketFrameChunks;
  typedef WebSocketFrameChunks::iterator iterator;
  typedef WebSocketFrameChunks::const_iterator const_iterator;

  WebSocketFrameContainer()
      : frame_completed_(false),
        payload_size_bytes_(0),
        expected_payload_size_bytes_(0) {}
  ~WebSocketFrameContainer() { clear(); }

  void clear();

  const net::WebSocketFrameHeader* GetHeader() const {
    if (empty()) {
      return NULL;
    }

    return (*begin())->header.get();
  }

  bool IsControlFrame() const;
  bool IsDataFrame() const;
  bool IsContinuationFrame() const;

  enum ErrorCode {
    kErrorNone,
    kErrorMaxFrameSizeViolation,
    kErrorFirstChunkMissingHeader,
    kErrorHasExtraHeader,
    kErrorFrameAlreadyComplete,
    kErrorPayloadSizeSmallerThanHeader,
    kErrorPayloadSizeLargerThanHeader
  };

  bool IsFrameComplete() const { return frame_completed_; }

  bool IsFinalFrame() const {
    const net::WebSocketFrameHeader* const header = GetHeader();
    if (!header) {
      return false;
    }
    return (header && header->final);
  }

  // Note that this takes always ownership of the chunk.
  // Should only be called if IsFrameComplete() is false.
  // Note that if there is an error produced in the function, it will
  // leave the state of this object unchanged.
  ErrorCode Take(const net::WebSocketFrameChunk* chunk);

  iterator begin() { return chunks_.begin(); }
  iterator end() { return chunks_.end(); }
  const_iterator begin() const { return chunks_.begin(); }
  const_iterator end() const { return chunks_.end(); }
  const_iterator cbegin() const { return chunks_.begin(); }
  const_iterator cend() const { return chunks_.end(); }
  bool empty() const { return begin() == end(); }

  std::size_t GetCurrentPayloadSizeBytes() const { return payload_size_bytes_; }
  std::size_t GetChunkCount() const { return chunks_.size(); }

  void swap(WebSocketFrameContainer& other) {
    std::swap(frame_completed_, other.frame_completed_);
    std::swap(payload_size_bytes_, other.payload_size_bytes_);
    std::swap(expected_payload_size_bytes_, other.expected_payload_size_bytes_);
    chunks_.swap(other.chunks_);
  }

  // Returns false if op_code was not found, and returns true otherwise.
  bool GetFrameOpCode(net::WebSocketFrameHeader::OpCode* op_code) const {
    DCHECK(op_code);
    if (empty()) {
      return false;
    }

    const net::WebSocketFrameChunk* first_chunk(*begin());
    DCHECK(first_chunk);
    const std::unique_ptr<net::WebSocketFrameHeader>& first_chunk_header =
        first_chunk->header;
    if (!first_chunk_header) {
      NOTREACHED() << "No header found in the first chunk.";
      return false;
    }

    *op_code = first_chunk_header->opcode;
    return true;
  }

 private:
  // Note: If you add a field, please remember to update swap() above.
  bool frame_completed_;
  std::size_t payload_size_bytes_;
  std::size_t expected_payload_size_bytes_;
  WebSocketFrameChunks chunks_;
};

}  // namespace websocket
}  // namespace cobalt

#endif  // COBALT_WEBSOCKET_WEB_SOCKET_FRAME_CONTAINER_H_
