// Copyright 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 "base/message_loop/message_pump_io_ios.h"

#include <unistd.h>

#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

class MessagePumpIOSForIOTest : public testing::Test {
 protected:
  MessagePumpIOSForIOTest()
      : ui_loop_(MessageLoop::TYPE_UI),
        io_thread_("MessagePumpIOSForIOTestIOThread") {}
  virtual ~MessagePumpIOSForIOTest() {}

  virtual void SetUp() OVERRIDE {
    Thread::Options options(MessageLoop::TYPE_IO, 0);
    ASSERT_TRUE(io_thread_.StartWithOptions(options));
    ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type());
    int ret = pipe(pipefds_);
    ASSERT_EQ(0, ret);
    ret = pipe(alternate_pipefds_);
    ASSERT_EQ(0, ret);
  }

  virtual void TearDown() OVERRIDE {
    if (IGNORE_EINTR(close(pipefds_[0])) < 0)
      PLOG(ERROR) << "close";
    if (IGNORE_EINTR(close(pipefds_[1])) < 0)
      PLOG(ERROR) << "close";
  }

  MessageLoop* ui_loop() { return &ui_loop_; }
  MessageLoopForIO* io_loop() const {
    return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
  }

  void HandleFdIOEvent(MessageLoopForIO::FileDescriptorWatcher* watcher) {
    MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_,
        kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
        watcher);
  }

  int pipefds_[2];
  int alternate_pipefds_[2];

 private:
  MessageLoop ui_loop_;
  Thread io_thread_;

  DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIOTest);
};

namespace {

// Concrete implementation of MessagePumpIOSForIO::Watcher that does
// nothing useful.
class StupidWatcher : public MessagePumpIOSForIO::Watcher {
 public:
  virtual ~StupidWatcher() {}

  // base:MessagePumpIOSForIO::Watcher interface
  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
};

#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)

// Test to make sure that we catch calling WatchFileDescriptor off of the
//  wrong thread.
TEST_F(MessagePumpIOSForIOTest, TestWatchingFromBadThread) {
  MessagePumpIOSForIO::FileDescriptorWatcher watcher;
  StupidWatcher delegate;

  ASSERT_DEBUG_DEATH(io_loop()->WatchFileDescriptor(
      STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
      "Check failed: "
      "watch_file_descriptor_caller_checker_.CalledOnValidThread\\(\\)");
}

#endif  // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)

class BaseWatcher : public MessagePumpIOSForIO::Watcher {
 public:
  BaseWatcher(MessagePumpIOSForIO::FileDescriptorWatcher* controller)
      : controller_(controller) {
    DCHECK(controller_);
  }
  virtual ~BaseWatcher() {}

  // MessagePumpIOSForIO::Watcher interface
  virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
    NOTREACHED();
  }

  virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
    NOTREACHED();
  }

 protected:
  MessagePumpIOSForIO::FileDescriptorWatcher* controller_;
};

class DeleteWatcher : public BaseWatcher {
 public:
  explicit DeleteWatcher(
      MessagePumpIOSForIO::FileDescriptorWatcher* controller)
      : BaseWatcher(controller) {}

  virtual ~DeleteWatcher() {
    DCHECK(!controller_);
  }

  virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
    DCHECK(controller_);
    delete controller_;
    controller_ = NULL;
  }
};

TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
  scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  MessagePumpIOSForIO::FileDescriptorWatcher* watcher =
      new MessagePumpIOSForIO::FileDescriptorWatcher;
  DeleteWatcher delegate(watcher);
  pump->WatchFileDescriptor(pipefds_[1],
      false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);

  // Spoof a callback.
  HandleFdIOEvent(watcher);
}

class StopWatcher : public BaseWatcher {
 public:
  StopWatcher(MessagePumpIOSForIO::FileDescriptorWatcher* controller,
              MessagePumpIOSForIO* pump,
              int fd_to_start_watching = -1)
      : BaseWatcher(controller),
        pump_(pump),
        fd_to_start_watching_(fd_to_start_watching) {}

  virtual ~StopWatcher() {}

  virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
    controller_->StopWatchingFileDescriptor();
    if (fd_to_start_watching_ >= 0) {
      pump_->WatchFileDescriptor(fd_to_start_watching_,
          false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
    }
  }

 private:
  MessagePumpIOSForIO* pump_;
  int fd_to_start_watching_;
};

TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
  scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  MessagePumpIOSForIO::FileDescriptorWatcher watcher;
  StopWatcher delegate(&watcher, pump.get());
  pump->WatchFileDescriptor(pipefds_[1],
      false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);

  // Spoof a callback.
  HandleFdIOEvent(&watcher);
}

TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
  scoped_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  MessagePumpIOSForIO::FileDescriptorWatcher watcher;
  StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
  pump->WatchFileDescriptor(pipefds_[1],
      false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);

  // Spoof a callback.
  HandleFdIOEvent(&watcher);
}

}  // namespace

}  // namespace base
