// 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) {}

  virtual ~ServerDelegate() {
    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_->message_loop_proxy()->PostTask(
        FROM_HERE,
        base::Bind(&ServerDelegate::DeleteControllerOnInternalThread,
                   base::Unretained(this)));
  }

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

  // Daemon::ServerDelegate:
  virtual 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();
  }

  virtual 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:
  virtual 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(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) {
  CommandLine::Init(argc, argv);  // Needed by logging.
  const bool kill_server = 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);
}
