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

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "examples/indirect_service/indirect_service_demo.mojom.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/common/message_pump_mojo.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"

namespace mojo {
namespace examples {

class DemoTask;

typedef base::Callback<void(DemoTask*, const std::vector<int32_t>&)>
    DemoTaskFinishedCallback;

// A thread that connects to the IndirectIntegerService, gets a connection
// to its IntegerService, and then calls Increment() iteration_count times.
// The results are saved and returned with the finished_callback.
class DemoTask {
 public:
  DemoTask(ScopedMessagePipeHandle proxy_handle,
           const DemoTaskFinishedCallback& finished_callback,
           unsigned iteration_count)
    : proxy_handle_(proxy_handle.Pass()),
      thread_("DemoTask"),
      finished_callback_(finished_callback),
      iteration_count_(iteration_count) {

    base::Thread::Options options;
    options.message_loop_type = base::MessageLoop::TYPE_CUSTOM;
    options.message_pump_factory = base::Bind(&common::MessagePumpMojo::Create);
    CHECK(thread_.StartWithOptions(options));

    thread_.message_loop()->PostTask(
        FROM_HERE, base::Bind(&DemoTask::Run, base::Unretained(this)));
  }

  void Run() {
    integer_service_.Bind(proxy_handle_.Pass());
    base::Callback<void(int32_t)> callback =
        base::Bind(&DemoTask::SaveResultAndFinish, base::Unretained(this));
    for(int unsigned i = 0; i < iteration_count_; i++) {
      integer_service_->Increment(callback);
      // To ensure that the DemoTask threads' execution overlaps, sleep.
      if (i < iteration_count_ - 1)
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(rand() % 10));
    }
  }

 private:
  void SaveResultAndFinish(int32_t result) {
    results_.push_back(result);
    if (results_.size() == iteration_count_) {
      integer_service_.reset(); // Must be done on thread_.
      finished_callback_.Run(this, results_);
    }
  }

  ScopedMessagePipeHandle proxy_handle_;
  base::Thread thread_;
  IntegerServicePtr integer_service_;
  DemoTaskFinishedCallback finished_callback_;
  unsigned iteration_count_;
  std::vector<int32_t> results_;
};

// Connect to the IntegerService and give its proxy to the
// IndirectIntegerService. Start kTaskCount DemoTask threads all of
// which will use the IndirectIntegerService to get their own connection
// to the (one) IntegerService. Each DemoTask will call the IntegerService's
// Increment() method kTaskIterationCount times, collect the results in
// a vector and return them to FinishDemoTask.
//
// The IntegerService, whose value is initially 0, will be called a total of
// N = |kTaskCount * kTaskIterationCount| times. Each DemoTask's results
// are displayed in array of length N. Digits appear in positions that
// correspond to the results obtained by the DemoTask thread. The results
// show that the DemoTask threads are accessing the Integer in parallel.
// The fact that only one digit appears in each column shows that things
// are working correctly.
class IndirectServiceDemoAppDelegate : public ApplicationDelegate {
 public:
  void Initialize(ApplicationImpl* app) override {
    IntegerServicePtr indirect_service_delegate;
    app->ConnectToService("mojo:indirect_integer_service",
        &indirect_integer_service_);
    app->ConnectToService("mojo:integer_service", &indirect_service_delegate);
    indirect_integer_service_->Set(indirect_service_delegate.Pass());

    for (unsigned i = 0; i < kTaskCount; i++) {
      IntegerServicePtr integer_service;
      indirect_integer_service_->Get(GetProxy(&integer_service));
      DemoTaskFinishedCallback finished_callback = base::Bind(
          &IndirectServiceDemoAppDelegate::FinishDemoTask,
          base::Unretained(this),
          base::Unretained(base::MessageLoop::current()));
      // We're passing the integer_service_ proxy to another thread, so
      // use its MessagePipe.
      tasks_.push_back(new DemoTask(integer_service.PassMessagePipe(),
                                    finished_callback,
                                    kTaskIterationCount));
    }
  }

 private:
  static const unsigned kTaskCount = 10;
  static const unsigned kTaskIterationCount = 6;

  // This method is called on a DemoTask thread. It just calls DoFinishDemoTask
  // on the application's run loop. Doing so serializes the DoFinishDemoTask
  // calls.
  void FinishDemoTask(base::MessageLoop *run_loop,
                      DemoTask* task,
                      const std::vector<int32_t>& results) {
    run_loop->PostTask(FROM_HERE, base::Bind(
        &IndirectServiceDemoAppDelegate::DoFinishDemoTask,
        base::Unretained(this),
        base::Unretained(task),
        results));
  }

  void DoFinishDemoTask(DemoTask* task, const std::vector<int32_t>& results) {
    std::string display(kTaskCount * kTaskIterationCount, ' ');
    for (unsigned i = 0; i < results.size(); i++)
      display[results[i]] = '0' + (results[i] % 10);
    printf("DemoTask Thread [%s]\n", display.c_str());
    tasks_.erase(std::remove(tasks_.begin(), tasks_.end(), task), tasks_.end());
    delete task; // Stop the DemoTask's thread etc.
    if (tasks_.empty())
      ApplicationImpl::Terminate();
  }

  IndirectIntegerServicePtr indirect_integer_service_;
  std::vector<DemoTask*> tasks_;
};


}  // namespace examples
}  // namespace mojo

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