// Copyright 2015 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 <stdio.h>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "examples/echo/echo.mojom.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/common/tracing_impl.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/cpp/utility/run_loop.h"

namespace mojo {
namespace examples {

static const base::TimeDelta kWarmupTime =
    base::TimeDelta::FromMilliseconds(1000);

static const base::TimeDelta kDelayTime = base::TimeDelta::FromMicroseconds(50);

class EchoClientDelegate;

class EchoResponse {
 public:
  EchoResponse(EchoClientDelegate* echo, int idx, bool traced)
      : echoDelegate_(echo), idx_(idx), traced_(traced) {}

  void Run(const String& value) const;

 private:
  EchoClientDelegate* echoDelegate_;
  int idx_;
  bool traced_;
};

class EchoClientDelegate : public ApplicationDelegate {
 public:
  EchoClientDelegate()
      : warmup_(true),
        num_clients_(1),
        num_active_clients_(1),
        use_dart_server_(false),
        ending_(false),
        benchmark_duration_(base::TimeDelta::FromSeconds(10)) {}

  void Initialize(ApplicationImpl* app) override {
    tracing_.Initialize(app->shell(), &app->args());

    ParseArguments(app);

    for (int i = 0; i < num_clients_; i++) {
      EchoPtr echo;
      if (use_dart_server_) {
        ConnectToService(app->shell(), "mojo:dart_echo_server",
                         GetProxy(&echo));
      } else {
        ConnectToService(app->shell(), "mojo:echo_server", GetProxy(&echo));
      }
      echoClients_.push_back(echo.Pass());
    }
    BeginEcho(0);
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&EchoClientDelegate::EndWarmup, base::Unretained(this)),
        kWarmupTime);
  }

  void BeginEcho(int idx) {
    if (ending_) return;
    if (idx == num_active_clients_) {
      idx = 0;
    }
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&EchoClientDelegate::Run, base::Unretained(this), idx),
        kDelayTime);
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&EchoClientDelegate::EndRun, base::Unretained(this)),
        benchmark_duration_);
  }

  void EndEcho(int idx, bool traced) {
    if (traced) {
      TRACE_EVENT_ASYNC_END0("echo_benchmark", "ping", echoClients_[idx].get());
    }
  }

 private:
  void Run(int idx) {
    if (ending_) return;
    if (warmup_) {
      echoClients_[idx]->EchoString("ping", EchoResponse(this, idx, false));
    } else {
      TRACE_EVENT_ASYNC_BEGIN0("echo_benchmark", "ping",
                               echoClients_[idx].get());
      echoClients_[idx]->EchoString("ping", EchoResponse(this, idx, true));
    }
  }

  bool GetBoolArgument(const std::string& argument,
                       const std::string& flag,
                       bool* value) {
    size_t start_pos = argument.find(flag);
    if (start_pos != std::string::npos) {
      *value = true;
      return true;
    }
    return false;
  }

  bool GetIntegerArgument(const std::string& argument,
                          const std::string& flag,
                          int* value) {
    size_t start_pos = argument.find(flag);
    if (start_pos != std::string::npos) {
      size_t equals_pos = argument.find("=", start_pos);
      if (equals_pos != std::string::npos) {
        base::StringToInt(argument.substr(equals_pos + 1), value);
        return true;
      }
    }
    return false;
  }

  void ParseArguments(ApplicationImpl* app) {
    int benchmark_duration_seconds = 0;
    for (size_t i = 0; i < app->args().size(); i++) {
      const std::string& argument = app->args()[i];
      if (GetBoolArgument(argument, "--dart-server", &use_dart_server_)) {
        continue;
      }
      if (GetIntegerArgument(argument, "--num-clients", &num_clients_)) {
        continue;
      }
      if (GetIntegerArgument(argument, "--num-active-clients",
                             &num_active_clients_)) {
        continue;
      }
      if (GetIntegerArgument(argument, "--benchmark-duration",
                             &benchmark_duration_seconds)) {
        benchmark_duration_ =
            base::TimeDelta::FromSeconds(benchmark_duration_seconds);
        continue;
      }
    }
  }

  void EndRun() { ending_ = true; }

  void EndWarmup() { warmup_ = false; }

  bool warmup_;
  int num_clients_;
  int num_active_clients_;
  bool use_dart_server_;
  bool ending_;
  base::TimeDelta benchmark_duration_;
  std::vector<EchoPtr> echoClients_;
  mojo::TracingImpl tracing_;
};

void EchoResponse::Run(const String& value) const {
  echoDelegate_->EndEcho(idx_, traced_);
  echoDelegate_->BeginEcho(idx_ + 1);
}

}  // namespace examples
}  // namespace mojo

MojoResult MojoMain(MojoHandle application_request) {
  mojo::ApplicationRunnerChromium runner(
      new mojo::examples::EchoClientDelegate);
  return runner.Run(application_request);
}
