// Copyright (c) 2012 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 <signal.h>
#include <stdlib.h>

#include <iostream>
#include <string>

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "tools/android/forwarder2/common.h"
#include "tools/android/forwarder2/daemon.h"
#include "tools/android/forwarder2/device_controller.h"
#include "tools/android/forwarder2/pipe_notifier.h"

namespace forwarder2 {
namespace {

// Leaky global instance, accessed from the signal handler.
forwarder2::PipeNotifier* g_notifier = NULL;

const int kBufSize = 256;

const char kUnixDomainSocketPath[] = "chrome_device_forwarder";
const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon";

void KillHandler(int /* unused */) {
  CHECK(g_notifier);
  if (!g_notifier->Notify())
    exit(1);
}

// Lets the daemon fetch the exit notifier file descriptor.
int GetExitNotifierFD() {
  DCHECK(g_notifier);
  return g_notifier->receiver_fd();
}

class ServerDelegate : public Daemon::ServerDelegate {
 public:
  ServerDelegate() : initialized_(false) {}

  ~ServerDelegate() override {
    if (!controller_thread_.get())
      return;
    // The DeviceController instance, if any, is constructed on the controller
    // thread. Make sure that it gets deleted on that same thread. Note that
    // DeleteSoon() is not used here since it would imply reading |controller_|
    // from the main thread while it's set on the internal thread.
    controller_thread_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&ServerDelegate::DeleteControllerOnInternalThread,
                   base::Unretained(this)));
  }

  void DeleteControllerOnInternalThread() {
    DCHECK(
        controller_thread_->task_runner()->RunsTasksOnCurrentThread());
    controller_.reset();
  }

  // Daemon::ServerDelegate:
  void Init() override {
    DCHECK(!g_notifier);
    g_notifier = new forwarder2::PipeNotifier();
    signal(SIGTERM, KillHandler);
    signal(SIGINT, KillHandler);
    controller_thread_.reset(new base::Thread("controller_thread"));
    controller_thread_->Start();
  }

  void OnClientConnected(scoped_ptr<Socket> client_socket) override {
    if (initialized_) {
      client_socket->WriteString("OK");
      return;
    }
    controller_thread_->message_loop()->PostTask(
        FROM_HERE,
        base::Bind(&ServerDelegate::StartController, base::Unretained(this),
                   GetExitNotifierFD(), base::Passed(&client_socket)));
    initialized_ = true;
  }

 private:
  void StartController(int exit_notifier_fd, scoped_ptr<Socket> client_socket) {
    DCHECK(!controller_.get());
    scoped_ptr<DeviceController> controller(
        DeviceController::Create(kUnixDomainSocketPath, exit_notifier_fd));
    if (!controller.get()) {
      client_socket->WriteString(
          base::StringPrintf("ERROR: Could not initialize device controller "
                             "with ADB socket path: %s",
                             kUnixDomainSocketPath));
      return;
    }
    controller_.swap(controller);
    controller_->Start();
    client_socket->WriteString("OK");
    client_socket->Close();
  }

  scoped_ptr<DeviceController> controller_;
  scoped_ptr<base::Thread> controller_thread_;
  bool initialized_;
};

class ClientDelegate : public Daemon::ClientDelegate {
 public:
  ClientDelegate() : has_failed_(false) {}

  bool has_failed() const { return has_failed_; }

  // Daemon::ClientDelegate:
  void OnDaemonReady(Socket* daemon_socket) override {
    char buf[kBufSize];
    const int bytes_read = daemon_socket->Read(
        buf, sizeof(buf) - 1 /* leave space for null terminator */);
    CHECK_GT(bytes_read, 0);
    DCHECK(static_cast<unsigned int>(bytes_read) < sizeof(buf));
    buf[bytes_read] = 0;
    base::StringPiece msg(buf, bytes_read);
    if (msg.starts_with("ERROR")) {
      LOG(ERROR) << msg;
      has_failed_ = true;
      return;
    }
  }

 private:
  bool has_failed_;
};

int RunDeviceForwarder(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);  // Needed by logging.
  const bool kill_server =
      base::CommandLine::ForCurrentProcess()->HasSwitch("kill-server");
  if ((kill_server && argc != 2) || (!kill_server && argc != 1)) {
    std::cerr << "Usage: device_forwarder [--kill-server]" << std::endl;
    return 1;
  }
  base::AtExitManager at_exit_manager;  // Used by base::Thread.
  ClientDelegate client_delegate;
  ServerDelegate daemon_delegate;
  const char kLogFilePath[] = "";  // Log to logcat.
  Daemon daemon(kLogFilePath, kDaemonIdentifier, &client_delegate,
                &daemon_delegate, &GetExitNotifierFD);

  if (kill_server)
    return !daemon.Kill();

  if (!daemon.SpawnIfNeeded())
    return 1;
  return client_delegate.has_failed();
}

}  // namespace
}  // namespace forwarder2

int main(int argc, char** argv) {
  return forwarder2::RunDeviceForwarder(argc, argv);
}
