// 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 "media/audio/async_socket_io_handler.h"

#include "base/bind.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
const char kAsyncSocketIoTestString[] = "Hello, AsyncSocketIoHandler";
const size_t kAsyncSocketIoTestStringLength =
    arraysize(kAsyncSocketIoTestString);

class TestSocketReader {
 public:
  // Set |number_of_reads_before_quit| to >0 when you expect a specific number
  // of Read operations to complete.  Once that number is reached, the current
  // message loop will be Quit().  Set |number_of_reads_before_quit| to -1 if
  // callbacks should not be counted.
  TestSocketReader(base::CancelableSyncSocket* socket,
                   int number_of_reads_before_quit,
                   bool issue_reads_from_callback)
      : socket_(socket), buffer_(),
        number_of_reads_before_quit_(number_of_reads_before_quit),
        callbacks_received_(0),
        issue_reads_from_callback_(issue_reads_from_callback) {
    io_handler.Initialize(socket_->handle(),
                          base::Bind(&TestSocketReader::OnRead,
                                     base::Unretained(this)));
  }
  ~TestSocketReader() {}

  bool IssueRead() {
    return io_handler.Read(&buffer_[0], sizeof(buffer_));
  }

  const char* buffer() const { return &buffer_[0]; }

  int callbacks_received() const { return callbacks_received_; }

 private:
  void OnRead(int bytes_read) {
    EXPECT_GT(bytes_read, 0);
    ++callbacks_received_;
    if (number_of_reads_before_quit_ == callbacks_received_) {
      MessageLoop::current()->Quit();
    } else if (issue_reads_from_callback_) {
      IssueRead();
    }
  }

  media::AsyncSocketIoHandler io_handler;
  base::CancelableSyncSocket* socket_;  // Ownership lies outside the class.
  char buffer_[kAsyncSocketIoTestStringLength];
  int number_of_reads_before_quit_;
  int callbacks_received_;
  bool issue_reads_from_callback_;
};

// Workaround to be able to use a base::Closure for sending data.
// Send() returns int but a closure must return void.
void SendData(base::CancelableSyncSocket* socket,
              const void* buffer,
              size_t length) {
  socket->Send(buffer, length);
}

}  // end namespace.

// Tests doing a pending read from a socket and use an IO handler to get
// notified of data.
TEST(AsyncSocketIoHandlerTest, AsynchronousReadWithMessageLoop) {
  MessageLoopForIO loop;

  base::CancelableSyncSocket pair[2];
  ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));

  TestSocketReader reader(&pair[0], 1, false);
  EXPECT_TRUE(reader.IssueRead());

  pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
  MessageLoop::current()->Run();
  EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
  EXPECT_EQ(1, reader.callbacks_received());
}

// Tests doing a read from a socket when we know that there is data in the
// socket.  Here we want to make sure that any async 'can read' notifications
// won't trip us off and that the synchronous case works as well.
TEST(AsyncSocketIoHandlerTest, SynchronousReadWithMessageLoop) {
  MessageLoopForIO loop;

  base::CancelableSyncSocket pair[2];
  ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));

  TestSocketReader reader(&pair[0], -1, false);

  pair[1].Send(kAsyncSocketIoTestString, kAsyncSocketIoTestStringLength);
  MessageLoop::current()->PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
      base::TimeDelta::FromMilliseconds(100));
  MessageLoop::current()->Run();

  EXPECT_TRUE(reader.IssueRead());
  EXPECT_EQ(strcmp(reader.buffer(), kAsyncSocketIoTestString), 0);
  // We've now verified that the read happened synchronously, but it's not
  // guaranteed that the callback has been issued since the callback will be
  // called asynchronously even though the read may have been done.
  // So we call RunUntilIdle() to allow any event notifications or APC's on
  // Windows, to execute before checking the count of how many callbacks we've
  // received.
  MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1, reader.callbacks_received());
}

// Calls Read() from within a callback to test that simple read "loops" work.
TEST(AsyncSocketIoHandlerTest, ReadFromCallback) {
  MessageLoopForIO loop;

  base::CancelableSyncSocket pair[2];
  ASSERT_TRUE(base::CancelableSyncSocket::CreatePair(&pair[0], &pair[1]));

  const int kReadOperationCount = 10;
  TestSocketReader reader(&pair[0], kReadOperationCount, true);
  EXPECT_TRUE(reader.IssueRead());

  // Issue sends on an interval to satisfy the Read() requirements.
  int64 milliseconds = 0;
  for (int i = 0; i < kReadOperationCount; ++i) {
    MessageLoop::current()->PostDelayedTask(FROM_HERE,
        base::Bind(&SendData, &pair[1], kAsyncSocketIoTestString,
            kAsyncSocketIoTestStringLength),
        base::TimeDelta::FromMilliseconds(milliseconds));
    milliseconds += 10;
  }

  MessageLoop::current()->PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
      base::TimeDelta::FromMilliseconds(100 + milliseconds));

  MessageLoop::current()->Run();
  EXPECT_EQ(kReadOperationCount, reader.callbacks_received());
}
