// 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/public/cpp/application/application_impl.h"

#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/lib/service_registry.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/environment/logging.h"

namespace mojo {

class ApplicationImpl::ShellPtrWatcher : public ErrorHandler {
 public:
  ShellPtrWatcher(ApplicationImpl* impl) : impl_(impl) {}

  ~ShellPtrWatcher() override {}

  void OnConnectionError() override { impl_->OnShellError(); }

 private:
  ApplicationImpl* impl_;
  MOJO_DISALLOW_COPY_AND_ASSIGN(ShellPtrWatcher);
};

ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate,
                                 ScopedMessagePipeHandle shell_handle)
    : initialized_(false), delegate_(delegate), shell_watch_(nullptr) {
  BindShell(shell_handle.Pass());
}

ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate,
                                 MojoHandle shell_handle)
    : initialized_(false), delegate_(delegate), shell_watch_(nullptr) {
  BindShell(MakeScopedHandle(MessagePipeHandle(shell_handle)));
}

bool ApplicationImpl::HasArg(const std::string& arg) const {
  return std::find(args_.begin(), args_.end(), arg) != args_.end();
}

void ApplicationImpl::ClearConnections() {
  for (ServiceRegistryList::iterator i(incoming_service_registries_.begin());
       i != incoming_service_registries_.end();
       ++i)
    delete *i;
  for (ServiceRegistryList::iterator i(outgoing_service_registries_.begin());
       i != outgoing_service_registries_.end();
       ++i)
    delete *i;
  incoming_service_registries_.clear();
  outgoing_service_registries_.clear();
}

ApplicationImpl::~ApplicationImpl() {
  ClearConnections();
  delete shell_watch_;
}

ApplicationConnection* ApplicationImpl::ConnectToApplication(
    const String& application_url) {
  MOJO_CHECK(initialized_);
  ServiceProviderPtr local_services;
  InterfaceRequest<ServiceProvider> local_request = GetProxy(&local_services);
  ServiceProviderPtr remote_services;
  shell_->ConnectToApplication(application_url, GetProxy(&remote_services),
                               local_services.Pass());
  internal::ServiceRegistry* registry = new internal::ServiceRegistry(
      this, application_url, remote_services.Pass(), local_request.Pass());
  if (!delegate_->ConfigureOutgoingConnection(registry)) {
    delete registry;
    return nullptr;
  }
  outgoing_service_registries_.push_back(registry);
  return registry;
}

bool ApplicationImpl::WaitForInitialize() {
  MOJO_CHECK(!initialized_);
  bool result = shell_.WaitForIncomingMethodCall();
  MOJO_CHECK(initialized_ || !result);
  return result;
}

ScopedMessagePipeHandle ApplicationImpl::UnbindShell() {
  return shell_.PassMessagePipe();
}

void ApplicationImpl::Initialize(Array<String> args) {
  MOJO_CHECK(!initialized_);
  initialized_ = true;
  args_ = args.To<std::vector<std::string>>();
  delegate_->Initialize(this);
}

void ApplicationImpl::BindShell(ScopedMessagePipeHandle shell_handle) {
  shell_watch_ = new ShellPtrWatcher(this);
  shell_.Bind(shell_handle.Pass());
  shell_.set_client(this);
  shell_.set_error_handler(shell_watch_);
}

void ApplicationImpl::AcceptConnection(
    const String& requestor_url,
    InterfaceRequest<ServiceProvider> services,
    ServiceProviderPtr exposed_services) {
  internal::ServiceRegistry* registry = new internal::ServiceRegistry(
      this, requestor_url, exposed_services.Pass(), services.Pass());
  if (!delegate_->ConfigureIncomingConnection(registry)) {
    delete registry;
    return;
  }
  incoming_service_registries_.push_back(registry);
}

void ApplicationImpl::RequestQuit() {
  Terminate();
}

}  // namespace mojo
