// Copyright 2017 The Chromium OS 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 "midis/client_tracker.h"

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

#include <memory>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/check.h>
#include <base/location.h>
#include <base/logging.h>
#include <brillo/message_loops/message_loop.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/public/cpp/bindings/pending_receiver.h>
#include <mojo/public/cpp/bindings/pending_remote.h>
#include <mojo/public/cpp/bindings/receiver.h>
#include <mojo/public/cpp/system/invitation.h>

namespace {

constexpr char kMidisPipe[] = "arc-midis-pipe";

// Implementation of the MidisHost interface. This is used to
// get the actual MidisManager interface which is used by the client to
// communicate with midis.
// A request to initialize this should be initiated by the ArcBridgeHost.
//
// NOTE: It is expected that this class should only be instantiated once
// during the lifetime of the service. An error in the Message Pipe associated
// with this class is most likely an unrecoverable error, and will necessitate
// the restart of the midis service from Chrome.
class MidisHostImpl : public arc::mojom::MidisHost {
 public:
  // |client_tracker|, which must outlive MidisHostImpl, is owned by the caller.
  MidisHostImpl(mojo::PendingReceiver<arc::mojom::MidisHost> receiver,
                midis::ClientTracker* client_tracker);
  MidisHostImpl(const MidisHostImpl&) = delete;
  MidisHostImpl& operator=(const MidisHostImpl&) = delete;

  ~MidisHostImpl() override = default;

  // mojom::MidisHost:
  void Connect(mojo::PendingReceiver<arc::mojom::MidisServer> receiver,
               mojo::PendingRemote<arc::mojom::MidisClient> client) override;

 private:
  // It's safe to hold a raw pointer to ClientTracker since we can assume
  // that the lifecycle of ClientTracker is a superset of the lifecycle of
  // MidisHostImpl.
  midis::ClientTracker* client_tracker_;
  mojo::Receiver<arc::mojom::MidisHost> receiver_;
};

MidisHostImpl::MidisHostImpl(
    mojo::PendingReceiver<arc::mojom::MidisHost> receiver,
    midis::ClientTracker* client_tracker)
    : client_tracker_(client_tracker), receiver_(this, std::move(receiver)) {}

void MidisHostImpl::Connect(
    mojo::PendingReceiver<arc::mojom::MidisServer> receiver,
    mojo::PendingRemote<arc::mojom::MidisClient> client) {
  VLOG(1) << "Connect() called.";
  client_tracker_->MakeMojoClient(std::move(receiver), std::move(client));
}

}  // namespace

namespace midis {

void ClientTracker::MakeMojoClient(
    mojo::PendingReceiver<arc::mojom::MidisServer> receiver,
    mojo::PendingRemote<arc::mojom::MidisClient> client) {
  client_id_counter_++;
  VLOG(1) << "MakeMojoClient called.";
  auto new_cli = std::make_unique<Client>(
      device_tracker_, client_id_counter_,
      base::Bind(&ClientTracker::RemoveClient, weak_factory_.GetWeakPtr()),
      std::move(receiver), std::move(client));

  if (new_cli) {
    clients_.emplace(client_id_counter_, std::move(new_cli));
  }
}

ClientTracker::ClientTracker() : client_id_counter_(0), weak_factory_(this) {}

ClientTracker::~ClientTracker() {
  for (auto& client : clients_) {
    device_tracker_->RemoveClientFromDevices(client.first);
  }
  clients_.clear();
  ipc_support_ = nullptr;
}

void ClientTracker::InitClientTracker() {
  VLOG(1) << "Start client Mojo server.";

  mojo::core::Init();
  ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
      base::ThreadTaskRunnerHandle::Get(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
}

void ClientTracker::RemoveClient(uint32_t client_id) {
  // First delete all references to this device.
  device_tracker_->RemoveClientFromDevices(client_id);
  clients_.erase(client_id);
}

void ClientTracker::AcceptProxyConnection(base::ScopedFD fd) {
  DCHECK(sequence_checker_.CalledOnValidSequence());
  mojo::IncomingInvitation invitation = mojo::IncomingInvitation::Accept(
      mojo::PlatformChannelEndpoint(mojo::PlatformHandle(std::move(fd))));
  mojo::ScopedMessagePipeHandle child_pipe =
      invitation.ExtractMessagePipe(kMidisPipe);
  midis_host_ = std::make_unique<MidisHostImpl>(
      mojo::PendingReceiver<arc::mojom::MidisHost>(std::move(child_pipe)),
      this);
}

bool ClientTracker::IsProxyConnected() {
  return midis_host_ != nullptr;
}

}  // namespace midis
