// Copyright 2014 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 "mojo/edk/system/channel_manager.h"

#include "base/callback.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "base/task_runner.h"
#include "base/threading/simple_thread.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/system/channel.h"
#include "mojo/edk/system/channel_endpoint.h"
#include "mojo/edk/system/message_pipe_dispatcher.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace system {
namespace {

class ChannelManagerTest : public testing::Test {
 public:
  ChannelManagerTest()
      : message_loop_(base::MessageLoop::TYPE_IO),
        channel_manager_(&platform_support_,
                         message_loop_.task_runner(),
                         nullptr) {}
  ~ChannelManagerTest() override {}

 protected:
  ChannelManager& channel_manager() { return channel_manager_; }

 private:
  embedder::SimplePlatformSupport platform_support_;
  base::MessageLoop message_loop_;
  // Note: This should be *after* the above, since they must be initialized
  // before it (and should outlive it).
  ChannelManager channel_manager_;

  DISALLOW_COPY_AND_ASSIGN(ChannelManagerTest);
};

TEST_F(ChannelManagerTest, Basic) {
  embedder::PlatformChannelPair channel_pair;

  const ChannelId id = 1;
  scoped_refptr<MessagePipeDispatcher> d =
      channel_manager().CreateChannelOnIOThread(
          id, channel_pair.PassServerHandle());

  scoped_refptr<Channel> ch = channel_manager().GetChannel(id);
  EXPECT_TRUE(ch);
  // |ChannelManager| should have a ref.
  EXPECT_FALSE(ch->HasOneRef());

  channel_manager().WillShutdownChannel(id);
  // |ChannelManager| should still have a ref.
  EXPECT_FALSE(ch->HasOneRef());

  channel_manager().ShutdownChannelOnIOThread(id);
  // |ChannelManager| should have given up its ref.
  EXPECT_TRUE(ch->HasOneRef());

  EXPECT_EQ(MOJO_RESULT_OK, d->Close());
}

TEST_F(ChannelManagerTest, TwoChannels) {
  embedder::PlatformChannelPair channel_pair;

  const ChannelId id1 = 1;
  scoped_refptr<MessagePipeDispatcher> d1 =
      channel_manager().CreateChannelOnIOThread(
          id1, channel_pair.PassServerHandle());

  const ChannelId id2 = 2;
  scoped_refptr<MessagePipeDispatcher> d2 =
      channel_manager().CreateChannelOnIOThread(
          id2, channel_pair.PassClientHandle());

  scoped_refptr<Channel> ch1 = channel_manager().GetChannel(id1);
  EXPECT_TRUE(ch1);

  scoped_refptr<Channel> ch2 = channel_manager().GetChannel(id2);
  EXPECT_TRUE(ch2);

  // Calling |WillShutdownChannel()| multiple times (on |id1|) is okay.
  channel_manager().WillShutdownChannel(id1);
  channel_manager().WillShutdownChannel(id1);
  EXPECT_FALSE(ch1->HasOneRef());
  // Not calling |WillShutdownChannel()| (on |id2|) is okay too.

  channel_manager().ShutdownChannelOnIOThread(id1);
  EXPECT_TRUE(ch1->HasOneRef());
  channel_manager().ShutdownChannelOnIOThread(id2);
  EXPECT_TRUE(ch2->HasOneRef());

  EXPECT_EQ(MOJO_RESULT_OK, d1->Close());
  EXPECT_EQ(MOJO_RESULT_OK, d2->Close());
}

class OtherThread : public base::SimpleThread {
 public:
  // Note: There should be no other refs to the channel identified by
  // |channel_id| outside the channel manager.
  OtherThread(scoped_refptr<base::TaskRunner> task_runner,
              ChannelManager* channel_manager,
              ChannelId channel_id,
              const base::Closure& quit_closure)
      : base::SimpleThread("other_thread"),
        task_runner_(task_runner),
        channel_manager_(channel_manager),
        channel_id_(channel_id),
        quit_closure_(quit_closure) {}
  ~OtherThread() override {}

 private:
  void Run() override {
    // TODO(vtl): Once we have a way of creating a channel from off the I/O
    // thread, do that here instead.

    // You can use any unique, nonzero value as the ID.
    scoped_refptr<Channel> ch = channel_manager_->GetChannel(channel_id_);
    // |ChannelManager| should have a ref.
    EXPECT_FALSE(ch->HasOneRef());

    channel_manager_->WillShutdownChannel(channel_id_);
    // |ChannelManager| should still have a ref.
    EXPECT_FALSE(ch->HasOneRef());

    {
      base::MessageLoop message_loop;
      base::RunLoop run_loop;
      channel_manager_->ShutdownChannel(channel_id_, run_loop.QuitClosure(),
                                        message_loop.task_runner());
      run_loop.Run();
    }

    CHECK(task_runner_->PostTask(FROM_HERE, quit_closure_));
  }

  scoped_refptr<base::TaskRunner> task_runner_;
  ChannelManager* channel_manager_;
  ChannelId channel_id_;
  base::Closure quit_closure_;

  DISALLOW_COPY_AND_ASSIGN(OtherThread);
};

TEST_F(ChannelManagerTest, CallsFromOtherThread) {
  embedder::PlatformChannelPair channel_pair;

  const ChannelId id = 1;
  scoped_refptr<MessagePipeDispatcher> d =
      channel_manager().CreateChannelOnIOThread(
          id, channel_pair.PassServerHandle());

  base::RunLoop run_loop;
  OtherThread thread(base::MessageLoopProxy::current(), &channel_manager(), id,
                     run_loop.QuitClosure());
  thread.Start();
  run_loop.Run();
  thread.Join();

  EXPECT_EQ(MOJO_RESULT_OK, d->Close());
}

}  // namespace
}  // namespace system
}  // namespace mojo
