// Copyright 2017 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 <memory>

#include "base/message_loop/message_loop.h"
#include "base/process/process_metrics.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/perf_log.h"
#include "base/timer/timer.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_perftest_messages.h"
#include "ipc/ipc_perftest_util.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_test.mojom.h"
#include "ipc/ipc_test_base.h"
#include "mojo/core/test/mojo_test_base.h"
#include "mojo/core/test/multiprocess_test_helper.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/message_pipe.h"

namespace IPC {
namespace {

struct TestParams {
  TestParams() = default;
  TestParams(size_t in_message_size,
             size_t in_frames_per_second,
             size_t in_messages_per_frame,
             size_t in_duration_in_seconds)
      : message_size(in_message_size),
        frames_per_second(in_frames_per_second),
        messages_per_frame(in_messages_per_frame),
        duration_in_seconds(in_duration_in_seconds) {}

  size_t message_size;
  size_t frames_per_second;
  size_t messages_per_frame;
  size_t duration_in_seconds;
};

std::vector<TestParams> GetDefaultTestParams() {
  std::vector<TestParams> list;
  list.push_back({144, 20, 10, 10});
  list.push_back({144, 60, 10, 10});
  return list;
}

std::string GetLogTitle(const std::string& label, const TestParams& params) {
  return base::StringPrintf(
      "%s_MsgSize_%zu_FrmPerSec_%zu_MsgPerFrm_%zu", label.c_str(),
      params.message_size, params.frames_per_second, params.messages_per_frame);
}

base::TimeDelta GetFrameTime(size_t frames_per_second) {
  return base::TimeDelta::FromSecondsD(1.0 / frames_per_second);
}

class PerfCpuLogger {
 public:
  explicit PerfCpuLogger(base::StringPiece test_name)
      : test_name_(test_name),
        process_metrics_(base::ProcessMetrics::CreateCurrentProcessMetrics()) {
    process_metrics_->GetPlatformIndependentCPUUsage();
  }

  ~PerfCpuLogger() {
    double result = process_metrics_->GetPlatformIndependentCPUUsage();
    base::LogPerfResult(test_name_.c_str(), result, "%");
  }

 private:
  std::string test_name_;
  std::unique_ptr<base::ProcessMetrics> process_metrics_;

  DISALLOW_COPY_AND_ASSIGN(PerfCpuLogger);
};

MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
  MojoPerfTestClient client;
  int rv = mojo::core::test::MultiprocessTestHelper::RunClientMain(
      base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)),
      true /* pass_pipe_ownership_to_main */);

  base::RunLoop run_loop;
  run_loop.RunUntilIdle();

  return rv;
}

class ChannelSteadyPingPongListener : public Listener {
 public:
  ChannelSteadyPingPongListener() = default;

  ~ChannelSteadyPingPongListener() override = default;

  void Init(Sender* sender) {
    DCHECK(!sender_);
    sender_ = sender;
  }

  void SetTestParams(const TestParams& params,
                     const std::string& label,
                     bool sync,
                     const base::Closure& quit_closure) {
    params_ = params;
    label_ = label;
    sync_ = sync;
    quit_closure_ = quit_closure;
    payload_ = std::string(params.message_size, 'a');
  }

  bool OnMessageReceived(const Message& message) override {
    CHECK(sender_);

    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(ChannelSteadyPingPongListener, message)
      IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
      IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
    return handled;
  }

  void OnHello() {
    cpu_logger_ = std::make_unique<PerfCpuLogger>(GetLogTitle(label_, params_));

    frame_count_down_ = params_.frames_per_second * params_.duration_in_seconds;

    timer_.Start(FROM_HERE, GetFrameTime(params_.frames_per_second), this,
                 &ChannelSteadyPingPongListener::StartPingPong);
  }

  void StartPingPong() {
    if (sync_) {
      base::TimeTicks before = base::TimeTicks::Now();
      for (count_down_ = params_.messages_per_frame; count_down_ > 0;
           --count_down_) {
        std::string response;
        sender_->Send(new TestMsg_SyncPing(payload_, &response));
        DCHECK_EQ(response, payload_);
      }

      if (base::TimeTicks::Now() - before >
          GetFrameTime(params_.frames_per_second)) {
        LOG(ERROR) << "Frame " << frame_count_down_
                   << " wasn't able to complete on time!";
      }

      CHECK_GT(frame_count_down_, 0);
      frame_count_down_--;
      if (frame_count_down_ == 0)
        StopPingPong();
    } else {
      if (count_down_ != 0) {
        LOG(ERROR) << "Frame " << frame_count_down_
                   << " wasn't able to complete on time!";
      } else {
        SendPong();
      }
      count_down_ = params_.messages_per_frame;
    }
  }

  void StopPingPong() {
    cpu_logger_.reset();
    timer_.AbandonAndStop();
    quit_closure_.Run();
  }

  void OnPing(const std::string& payload) {
    // Include message deserialization in latency.
    DCHECK_EQ(payload_.size(), payload.size());

    CHECK_GT(count_down_, 0);
    count_down_--;
    if (count_down_ > 0) {
      SendPong();
    } else {
      CHECK_GT(frame_count_down_, 0);
      frame_count_down_--;
      if (frame_count_down_ == 0)
        StopPingPong();
    }
  }

  void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }

 private:
  Sender* sender_ = nullptr;
  TestParams params_;
  std::string payload_;
  std::string label_;
  bool sync_ = false;

  int count_down_ = 0;
  int frame_count_down_ = 0;

  base::RepeatingTimer timer_;
  std::unique_ptr<PerfCpuLogger> cpu_logger_;

  base::Closure quit_closure_;
};

class ChannelSteadyPingPongTest : public IPCChannelMojoTestBase {
 public:
  ChannelSteadyPingPongTest() = default;
  ~ChannelSteadyPingPongTest() override = default;

  void RunPingPongServer(const std::string& label, bool sync) {
    Init("MojoPerfTestClient");

    // Set up IPC channel and start client.
    ChannelSteadyPingPongListener listener;

    std::unique_ptr<ChannelProxy> channel_proxy;
    std::unique_ptr<base::WaitableEvent> shutdown_event;

    if (sync) {
      shutdown_event = std::make_unique<base::WaitableEvent>(
          base::WaitableEvent::ResetPolicy::MANUAL,
          base::WaitableEvent::InitialState::NOT_SIGNALED);
      channel_proxy = IPC::SyncChannel::Create(
          TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
          GetIOThreadTaskRunner(), base::ThreadTaskRunnerHandle::Get(), false,
          shutdown_event.get());
    } else {
      channel_proxy = IPC::ChannelProxy::Create(
          TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
          GetIOThreadTaskRunner(), base::ThreadTaskRunnerHandle::Get());
    }
    listener.Init(channel_proxy.get());

    LockThreadAffinity thread_locker(kSharedCore);
    std::vector<TestParams> params_list = GetDefaultTestParams();
    for (const auto& params : params_list) {
      base::RunLoop run_loop;

      listener.SetTestParams(params, label, sync,
                             run_loop.QuitWhenIdleClosure());

      // This initial message will kick-start the ping-pong of messages.
      channel_proxy->Send(new TestMsg_Hello);

      run_loop.Run();
    }

    // Send quit message.
    channel_proxy->Send(new TestMsg_Quit);

    EXPECT_TRUE(WaitForClientShutdown());
    channel_proxy.reset();
  }
};

TEST_F(ChannelSteadyPingPongTest, AsyncPingPong) {
  RunPingPongServer("IPC_CPU_Async", false);
}

TEST_F(ChannelSteadyPingPongTest, SyncPingPong) {
  RunPingPongServer("IPC_CPU_Sync", true);
}

class MojoSteadyPingPongTest : public mojo::core::test::MojoTestBase {
 public:
  MojoSteadyPingPongTest() = default;

 protected:
  void RunPingPongServer(MojoHandle mp, const std::string& label, bool sync) {
    label_ = label;
    sync_ = sync;

    mojo::MessagePipeHandle mp_handle(mp);
    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
    ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u));

    LockThreadAffinity thread_locker(kSharedCore);
    std::vector<TestParams> params_list = GetDefaultTestParams();
    for (const auto& params : params_list) {
      params_ = params;
      payload_ = std::string(params.message_size, 'a');

      ping_receiver_->Ping("hello", base::Bind(&MojoSteadyPingPongTest::OnHello,
                                               base::Unretained(this)));
      base::RunLoop run_loop;
      quit_closure_ = run_loop.QuitWhenIdleClosure();
      run_loop.Run();
    }

    ping_receiver_->Quit();

    ignore_result(ping_receiver_.PassInterface().PassHandle().release());
  }

  void OnHello(const std::string& value) {
    cpu_logger_ = std::make_unique<PerfCpuLogger>(GetLogTitle(label_, params_));

    frame_count_down_ = params_.frames_per_second * params_.duration_in_seconds;

    timer_.Start(FROM_HERE, GetFrameTime(params_.frames_per_second), this,
                 &MojoSteadyPingPongTest::StartPingPong);
  }

  void StartPingPong() {
    if (sync_) {
      base::TimeTicks before = base::TimeTicks::Now();
      for (count_down_ = params_.messages_per_frame; count_down_ > 0;
           --count_down_) {
        std::string response;
        ping_receiver_->SyncPing(payload_, &response);
        DCHECK_EQ(response, payload_);
      }

      if (base::TimeTicks::Now() - before >
          GetFrameTime(params_.frames_per_second)) {
        LOG(ERROR) << "Frame " << frame_count_down_
                   << " wasn't able to complete on time!";
      }

      CHECK_GT(frame_count_down_, 0);
      frame_count_down_--;
      if (frame_count_down_ == 0)
        StopPingPong();
    } else {
      if (count_down_ != 0) {
        LOG(ERROR) << "Frame " << frame_count_down_
                   << " wasn't able to complete on time!";
      } else {
        SendPing();
      }
      count_down_ = params_.messages_per_frame;
    }
  }

  void StopPingPong() {
    cpu_logger_.reset();
    timer_.AbandonAndStop();
    quit_closure_.Run();
  }

  void OnPong(const std::string& value) {
    // Include message deserialization in latency.
    DCHECK_EQ(payload_.size(), value.size());

    CHECK_GT(count_down_, 0);
    count_down_--;
    if (count_down_ > 0) {
      SendPing();
    } else {
      CHECK_GT(frame_count_down_, 0);
      frame_count_down_--;
      if (frame_count_down_ == 0)
        StopPingPong();
    }
  }

  void SendPing() {
    ping_receiver_->Ping(payload_, base::Bind(&MojoSteadyPingPongTest::OnPong,
                                              base::Unretained(this)));
  }

  static int RunPingPongClient(MojoHandle mp) {
    mojo::MessagePipeHandle mp_handle(mp);
    mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);

    LockThreadAffinity thread_locker(kSharedCore);
    base::RunLoop run_loop;
    ReflectorImpl impl(std::move(scoped_mp), run_loop.QuitWhenIdleClosure());
    run_loop.Run();
    return 0;
  }

 private:
  TestParams params_;
  std::string payload_;
  std::string label_;
  bool sync_ = false;

  IPC::mojom::ReflectorPtr ping_receiver_;

  int count_down_ = 0;
  int frame_count_down_ = 0;

  base::RepeatingTimer timer_;
  std::unique_ptr<PerfCpuLogger> cpu_logger_;

  base::Closure quit_closure_;

  DISALLOW_COPY_AND_ASSIGN(MojoSteadyPingPongTest);
};

DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoSteadyPingPongTest, h) {
  base::MessageLoop main_message_loop;
  return RunPingPongClient(h);
}

// Similar to ChannelSteadyPingPongTest above, but uses a Mojo interface
// instead of raw IPC::Messages.
TEST_F(MojoSteadyPingPongTest, AsyncPingPong) {
  RunTestClient("PingPongClient", [&](MojoHandle h) {
    base::MessageLoop main_message_loop;
    RunPingPongServer(h, "Mojo_CPU_Async", false);
  });
}

TEST_F(MojoSteadyPingPongTest, SyncPingPong) {
  RunTestClient("PingPongClient", [&](MojoHandle h) {
    base::MessageLoop main_message_loop;
    RunPingPongServer(h, "Mojo_CPU_Sync", true);
  });
}

}  // namespace
}  // namespace IPC
