// 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 "testing/gtest/include/gtest/gtest.h"

namespace {

const char payload_filler = '?';

}  // namespace

namespace cobalt {
namespace websocket {

class WebSocketMessageContainerTest : public ::testing::Test {
 public:
  WebSocketMessageContainerTest() {
    PopulateBinaryFrame(2);  // Create a final binary frame with 2 byte payload.
    PopulateTextFrame();
    PopulateContinuationFrame(3);
  }

 protected:
  void PopulateBinaryFrame(int payload_size) {
    net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
    chunk->header = make_scoped_ptr<net::WebSocketFrameHeader>(
        new net::WebSocketFrameHeader());
    chunk->header->final = true;
    chunk->header->payload_length = payload_size;
    chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeBinary;
    chunk->data = make_scoped_refptr<net::IOBufferWithSize>(
        new net::IOBufferWithSize(payload_size));
    chunk->final_chunk = true;
    WebSocketFrameContainer::ErrorCode error_code =
        final_binary_frame_.Take(chunk);
    EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
  }

  void PopulateTextFrame() {
    net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
    chunk->header = make_scoped_ptr<net::WebSocketFrameHeader>(
        new net::WebSocketFrameHeader());
    chunk->header->final = false;
    chunk->header->payload_length = 0;
    chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeText;
    chunk->final_chunk = true;
    WebSocketFrameContainer::ErrorCode error_code =
        nonfinal_text_frame_.Take(chunk);
    EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
  }

  void PopulateContinuationFrame(int payload_size) {
    net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
    chunk->header = make_scoped_ptr<net::WebSocketFrameHeader>(
        new net::WebSocketFrameHeader());
    chunk->header->final = true;
    chunk->header->payload_length = payload_size;
    chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeContinuation;
    chunk->data = make_scoped_refptr<net::IOBufferWithSize>(
        new net::IOBufferWithSize(payload_size));

    net::IOBufferWithSize& data_array(*chunk->data.get());
    SbMemorySet(data_array.data(), payload_filler, data_array.size());

    chunk->final_chunk = true;
    WebSocketFrameContainer::ErrorCode error_code =
        final_continuation_frame_.Take(chunk);
    EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
  }

  WebSocketFrameContainer final_binary_frame_;  // Final frame

  WebSocketFrameContainer nonfinal_text_frame_;  // Not a final frame.
  WebSocketFrameContainer final_continuation_frame_;

  WebSocketMessageContainer message_container_;
};

TEST_F(WebSocketMessageContainerTest, Construct) {
  EXPECT_TRUE(message_container_.empty());
  EXPECT_FALSE(message_container_.IsMessageComplete());
  EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
}

TEST_F(WebSocketMessageContainerTest, Clear) {
  EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
  message_container_.clear();
  EXPECT_TRUE(message_container_.empty());
  EXPECT_FALSE(message_container_.IsMessageComplete());
  EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
}

TEST_F(WebSocketMessageContainerTest, GetMessageOpCode) {
  net::WebSocketFrameHeader::OpCode op;
  EXPECT_FALSE(message_container_.GetMessageOpCode(&op));
  EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
  EXPECT_TRUE(message_container_.GetMessageOpCode(&op));
  EXPECT_EQ(op, net::WebSocketFrameHeader::kOpCodeBinary);
}

TEST_F(WebSocketMessageContainerTest, TakeMultipleFrames) {
  EXPECT_EQ(message_container_.GetFrames().size(), 0U);
  EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
  EXPECT_EQ(message_container_.GetFrames().size(), 1U);
  EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
  EXPECT_EQ(message_container_.GetFrames().size(), 2U);
}

TEST_F(WebSocketMessageContainerTest, IsMessageComplete) {
  EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
  EXPECT_TRUE(message_container_.IsMessageComplete());
}

TEST_F(WebSocketMessageContainerTest, IsMessageComplete2) {
  EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
  EXPECT_FALSE(message_container_.IsMessageComplete());
  EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
  EXPECT_TRUE(message_container_.IsMessageComplete());
}

TEST_F(WebSocketMessageContainerTest, IsTextMessage) {
  EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
  EXPECT_TRUE(message_container_.IsTextMessage());
}

TEST_F(WebSocketMessageContainerTest, IsTextMessage2) {
  EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
  EXPECT_FALSE(message_container_.IsTextMessage());
}

TEST_F(WebSocketMessageContainerTest, PayloadSize) {
  EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
  EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
  EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
  EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
  EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 3UL);
}

TEST_F(WebSocketMessageContainerTest, TakeStartsWithContinuationFrame) {
  EXPECT_FALSE(message_container_.Take(&final_continuation_frame_));
}

TEST_F(WebSocketMessageContainerTest, GetIOBuffer) {
  EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
  EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
  scoped_refptr<net::IOBufferWithSize> payload =
      message_container_.GetMessageAsIOBuffer();

  int payload_size = payload->size();
  EXPECT_GE(payload_size, 0);

  char* data = payload->data();
  for (int i = 0; i != payload_size; ++i) {
    DCHECK_EQ(payload_filler, data[i]);
  }
}

}  // namespace websocket
}  // namespace cobalt
