// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/websockets/websocket_inflater.h"

#include <stdint.h>
#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_deflater.h"
#include "net/websockets/websocket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

std::string ToString(IOBufferWithSize* buffer) {
  return std::string(buffer->data(), buffer->size());
}

TEST(WebSocketInflaterTest, Construct) {
  WebSocketInflater inflater;
  ASSERT_TRUE(inflater.Initialize(15));

  EXPECT_EQ(0u, inflater.CurrentOutputSize());
}

TEST(WebSocketInflaterTest, InflateHelloTakeOverContext) {
  WebSocketInflater inflater;
  ASSERT_TRUE(inflater.Initialize(15));
  scoped_refptr<IOBufferWithSize> actual1, actual2;

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  ASSERT_TRUE(actual1.get());
  EXPECT_EQ("Hello", ToString(actual1.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());

  ASSERT_TRUE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
  ASSERT_TRUE(inflater.Finish());
  actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
  ASSERT_TRUE(actual2.get());
  EXPECT_EQ("Hello", ToString(actual2.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());
}

TEST(WebSocketInflaterTest, InflateHelloSmallCapacity) {
  WebSocketInflater inflater(1, 1);
  ASSERT_TRUE(inflater.Initialize(15));
  std::string actual;

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  for (size_t i = 0; i < 5; ++i) {
    ASSERT_EQ(1u, inflater.CurrentOutputSize());
    scoped_refptr<IOBufferWithSize> buffer = inflater.GetOutput(1);
    ASSERT_TRUE(buffer.get());
    ASSERT_EQ(1, buffer->size());
    actual += ToString(buffer.get());
  }
  EXPECT_EQ("Hello", actual);
  EXPECT_EQ(0u, inflater.CurrentOutputSize());
}

TEST(WebSocketInflaterTest, InflateHelloSmallCapacityGetTotalOutput) {
  WebSocketInflater inflater(1, 1);
  ASSERT_TRUE(inflater.Initialize(15));
  scoped_refptr<IOBufferWithSize> actual;

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  ASSERT_EQ(1u, inflater.CurrentOutputSize());
  actual = inflater.GetOutput(1024);
  EXPECT_EQ("Hello", ToString(actual.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());
}

TEST(WebSocketInflaterTest, InflateInvalidData) {
  WebSocketInflater inflater;
  ASSERT_TRUE(inflater.Initialize(15));
  EXPECT_FALSE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
}

TEST(WebSocketInflaterTest, ChokedInvalidData) {
  WebSocketInflater inflater(1, 1);
  ASSERT_TRUE(inflater.Initialize(15));

  EXPECT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
  EXPECT_TRUE(inflater.Finish());
  EXPECT_EQ(1u, inflater.CurrentOutputSize());
  EXPECT_FALSE(inflater.GetOutput(1024).get());
}

TEST(WebSocketInflaterTest, MultipleAddBytesCalls) {
  WebSocketInflater inflater;
  ASSERT_TRUE(inflater.Initialize(15));
  std::string input("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
  scoped_refptr<IOBufferWithSize> actual;

  for (size_t i = 0; i < input.size(); ++i) {
    ASSERT_TRUE(inflater.AddBytes(&input[i], 1));
  }
  ASSERT_TRUE(inflater.Finish());
  actual = inflater.GetOutput(5);
  ASSERT_TRUE(actual.get());
  EXPECT_EQ("Hello", ToString(actual.get()));
}

TEST(WebSocketInflaterTest, Reset) {
  WebSocketInflater inflater;
  ASSERT_TRUE(inflater.Initialize(15));
  scoped_refptr<IOBufferWithSize> actual1, actual2;

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  ASSERT_TRUE(actual1.get());
  EXPECT_EQ("Hello", ToString(actual1.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());

  // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
  ASSERT_TRUE(inflater.AddBytes("\x01", 1));
  ASSERT_TRUE(inflater.Finish());
  ASSERT_EQ(0u, inflater.CurrentOutputSize());

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
  ASSERT_TRUE(actual2.get());
  EXPECT_EQ("Hello", ToString(actual2.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());
}

TEST(WebSocketInflaterTest, ResetAndLostContext) {
  WebSocketInflater inflater;
  scoped_refptr<IOBufferWithSize> actual1, actual2;
  ASSERT_TRUE(inflater.Initialize(15));

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
  ASSERT_TRUE(actual1.get());
  EXPECT_EQ("Hello", ToString(actual1.get()));
  EXPECT_EQ(0u, inflater.CurrentOutputSize());

  // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
  ASSERT_TRUE(inflater.AddBytes("\x01", 1));
  ASSERT_TRUE(inflater.Finish());
  ASSERT_EQ(0u, inflater.CurrentOutputSize());

  // The context is already reset.
  ASSERT_FALSE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
}

TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutput) {
  WebSocketInflater inflater;
  scoped_refptr<IOBufferWithSize> actual1, actual2;
  ASSERT_TRUE(inflater.Initialize(15));

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  EXPECT_EQ(5u, inflater.CurrentOutputSize());

  // This is a test for detecting memory leaks with valgrind.
}

TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutputChoked) {
  WebSocketInflater inflater(1, 1);
  scoped_refptr<IOBufferWithSize> actual1, actual2;
  ASSERT_TRUE(inflater.Initialize(15));

  ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
  ASSERT_TRUE(inflater.Finish());
  EXPECT_EQ(1u, inflater.CurrentOutputSize());

  // This is a test for detecting memory leaks with valgrind.
}

TEST(WebSocketInflaterTest, LargeRandomDeflateInflate) {
  const size_t size = 64 * 1024;
  LinearCongruentialGenerator generator(133);
  std::vector<char> input;
  std::vector<char> output;
  scoped_refptr<IOBufferWithSize> compressed;

  WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
  ASSERT_TRUE(deflater.Initialize(8));
  WebSocketInflater inflater(256, 256);
  ASSERT_TRUE(inflater.Initialize(8));

  for (size_t i = 0; i < size; ++i)
    input.push_back(static_cast<char>(generator.Generate()));

  ASSERT_TRUE(deflater.AddBytes(&input[0], input.size()));
  ASSERT_TRUE(deflater.Finish());

  compressed = deflater.GetOutput(deflater.CurrentOutputSize());

  ASSERT_TRUE(compressed.get());
  ASSERT_EQ(0u, deflater.CurrentOutputSize());

  ASSERT_TRUE(inflater.AddBytes(compressed->data(), compressed->size()));
  ASSERT_TRUE(inflater.Finish());

  while (inflater.CurrentOutputSize() > 0) {
    scoped_refptr<IOBufferWithSize> uncompressed =
        inflater.GetOutput(inflater.CurrentOutputSize());
    ASSERT_TRUE(uncompressed.get());
    output.insert(output.end(),
                  uncompressed->data(),
                  uncompressed->data() + uncompressed->size());
  }

  EXPECT_EQ(output, input);
}

}  // unnamed namespace

}  // namespace net
