// Copyright (c) 2012 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 "remoting/protocol/buffered_socket_writer.h"

#include <stdlib.h>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "remoting/protocol/fake_session.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {
namespace protocol {

namespace {
const int kTestBufferSize = 10 * 1024; // 10k;
const size_t kWriteChunkSize = 1024U;
}  // namespace

class BufferedSocketWriterTest : public testing::Test {
 public:
  BufferedSocketWriterTest()
      : write_error_(0) {
  }

  void OnDone() {
    base::MessageLoop::current()->PostTask(FROM_HERE,
                                           base::MessageLoop::QuitClosure());
  }

  void DestroyWriterAndQuit() {
    written_data_ = socket_->written_data();
    writer_.reset();
    socket_.reset();
    base::MessageLoop::current()->PostTask(FROM_HERE,
                                           base::MessageLoop::QuitClosure());
  }

  void Unexpected() {
    EXPECT_TRUE(false);
  }

 protected:
  virtual void SetUp() OVERRIDE {
    socket_.reset(new FakeSocket());
    writer_.reset(new BufferedSocketWriter());
    writer_->Init(socket_.get(), base::Bind(
        &BufferedSocketWriterTest::OnWriteFailed, base::Unretained(this)));
    test_buffer_ = new net::IOBufferWithSize(kTestBufferSize);
    test_buffer_2_ = new net::IOBufferWithSize(kTestBufferSize);
    for (int i = 0; i< kTestBufferSize; ++i) {
      test_buffer_->data()[i] = rand() % 256;
      test_buffer_2_->data()[i] = rand() % 256;
    }
  }

  void OnWriteFailed(int error) {
    write_error_ = error;
  }

  void TestWrite() {
    writer_->Write(test_buffer_, base::Bind(&BufferedSocketWriterTest::OnDone,
                                            base::Unretained(this)));
    writer_->Write(test_buffer_2_, base::Bind(&BufferedSocketWriterTest::OnDone,
                                              base::Unretained(this)));
    message_loop_.Run();
    ASSERT_EQ(static_cast<size_t>(test_buffer_->size() +
                                  test_buffer_2_->size()),
              socket_->written_data().size());
    EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(),
                        test_buffer_->size()));
    EXPECT_EQ(0, memcmp(test_buffer_2_->data(),
                        socket_->written_data().data() + test_buffer_->size(),
                        test_buffer_2_->size()));
  }

  void TestAppendInCallback() {
    writer_->Write(test_buffer_, base::Bind(
        base::IgnoreResult(&BufferedSocketWriterBase::Write),
        base::Unretained(writer_.get()), test_buffer_2_,
        base::Bind(&BufferedSocketWriterTest::OnDone,
                  base::Unretained(this))));
    message_loop_.Run();
    ASSERT_EQ(static_cast<size_t>(test_buffer_->size() +
                                  test_buffer_2_->size()),
              socket_->written_data().size());
    EXPECT_EQ(0, memcmp(test_buffer_->data(), socket_->written_data().data(),
                        test_buffer_->size()));
    EXPECT_EQ(0, memcmp(test_buffer_2_->data(),
                        socket_->written_data().data() + test_buffer_->size(),
                        test_buffer_2_->size()));
  }

  base::MessageLoop message_loop_;
  scoped_ptr<FakeSocket> socket_;
  scoped_ptr<BufferedSocketWriter> writer_;
  scoped_refptr<net::IOBufferWithSize> test_buffer_;
  scoped_refptr<net::IOBufferWithSize> test_buffer_2_;
  std::string written_data_;
  int write_error_;
};

// Test synchronous write.
TEST_F(BufferedSocketWriterTest, WriteFull) {
  TestWrite();
}

// Test synchronous write in 1k chunks.
TEST_F(BufferedSocketWriterTest, WriteChunks) {
  socket_->set_write_limit(kWriteChunkSize);
  TestWrite();
}

// Test asynchronous write.
TEST_F(BufferedSocketWriterTest, WriteAsync) {
  socket_->set_async_write(true);
  socket_->set_write_limit(kWriteChunkSize);
  TestWrite();
}

// Make sure we can call Write() from the done callback.
TEST_F(BufferedSocketWriterTest, AppendInCallbackSync) {
  TestAppendInCallback();
}

// Make sure we can call Write() from the done callback.
TEST_F(BufferedSocketWriterTest, AppendInCallbackAsync) {
  socket_->set_async_write(true);
  socket_->set_write_limit(kWriteChunkSize);
  TestAppendInCallback();
}

// Test that the writer can be destroyed from callback.
TEST_F(BufferedSocketWriterTest, DestroyFromCallback) {
  socket_->set_async_write(true);
  writer_->Write(test_buffer_, base::Bind(
      &BufferedSocketWriterTest::DestroyWriterAndQuit,
      base::Unretained(this)));
  writer_->Write(test_buffer_2_, base::Bind(
      &BufferedSocketWriterTest::Unexpected,
      base::Unretained(this)));
  socket_->set_async_write(false);
  message_loop_.Run();
  ASSERT_GE(written_data_.size(),
            static_cast<size_t>(test_buffer_->size()));
  EXPECT_EQ(0, memcmp(test_buffer_->data(), written_data_.data(),
                      test_buffer_->size()));
}

// Verify that it stops writing after the first error.
TEST_F(BufferedSocketWriterTest, TestWriteErrorSync) {
  socket_->set_write_limit(kWriteChunkSize);
  writer_->Write(test_buffer_, base::Closure());
  socket_->set_async_write(true);
  writer_->Write(test_buffer_2_,
                 base::Bind(&BufferedSocketWriterTest::Unexpected,
                            base::Unretained(this)));
  socket_->set_next_write_error(net::ERR_FAILED);
  socket_->set_async_write(false);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(net::ERR_FAILED, write_error_);
  EXPECT_EQ(static_cast<size_t>(test_buffer_->size()),
            socket_->written_data().size());
}

// Verify that it stops writing after the first error.
TEST_F(BufferedSocketWriterTest, TestWriteErrorAsync) {
  socket_->set_write_limit(kWriteChunkSize);
  writer_->Write(test_buffer_, base::Closure());
  socket_->set_async_write(true);
  writer_->Write(test_buffer_2_,
                 base::Bind(&BufferedSocketWriterTest::Unexpected,
                            base::Unretained(this)));
  socket_->set_next_write_error(net::ERR_FAILED);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(net::ERR_FAILED, write_error_);
  EXPECT_EQ(static_cast<size_t>(test_buffer_->size()),
            socket_->written_data().size());
}

}  // namespace protocol
}  // namespace remoting

