// 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
