// 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 "chromeos/ime/ibus_daemon_controller.h"

#include "base/bind.h"
#include "base/chromeos/chromeos_version.h"
#include "base/environment.h"
#include "base/files/file_path_watcher.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/observer_list.h"
#include "base/process/launch.h"
#include "base/process/process_handle.h"
#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_checker.h"
#include "chromeos/dbus/dbus_thread_manager.h"

namespace chromeos {

namespace {

IBusDaemonController* g_ibus_daemon_controller = NULL;
base::FilePathWatcher* g_file_path_watcher = NULL;

// Called when the ibus-daemon address file is modified.
static void OnFilePathChanged(
    const scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
    const base::Closure& closure,
    const base::FilePath& file_path,
    bool failed) {
  if (failed)
    return;  // Can't recover, do nothing.
  if (!g_file_path_watcher)
    return;  // Already discarded watch task.

  ui_task_runner->PostTask(FROM_HERE, closure);
  ui_task_runner->DeleteSoon(FROM_HERE, g_file_path_watcher);
  g_file_path_watcher = NULL;
}

// Start watching |address_file_path|. If the target file is changed, |callback|
// is called on UI thread. This function should be called on FILE thread.
void StartWatch(
    const std::string& address_file_path,
    const base::Closure& closure,
    const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) {
  // Before start watching, discard on-going watching task.
  delete g_file_path_watcher;
  g_file_path_watcher = new base::FilePathWatcher;
  bool result = g_file_path_watcher->Watch(
      base::FilePath::FromUTF8Unsafe(address_file_path),
      false,  // do not watch child directory.
      base::Bind(&OnFilePathChanged,
                 ui_task_runner,
                 closure));
  DCHECK(result);
}

// The implementation of IBusDaemonController.
class IBusDaemonControllerImpl : public IBusDaemonController {
 public:
  // Represents current ibus-daemon status.
  enum IBusDaemonStatus {
    IBUS_DAEMON_INITIALIZING,
    IBUS_DAEMON_RUNNING,
    IBUS_DAEMON_SHUTTING_DOWN,
    IBUS_DAEMON_STOP,
  };

  IBusDaemonControllerImpl(
      const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
      const scoped_refptr<base::SequencedTaskRunner>& file_task_runner)
      : process_handle_(base::kNullProcessHandle),
      ibus_daemon_status_(IBUS_DAEMON_STOP),
      ui_task_runner_(ui_task_runner),
      file_task_runner_(file_task_runner),
      weak_ptr_factory_(this) {
  }

  virtual ~IBusDaemonControllerImpl() {}

  // IBusDaemonController override:
  virtual void AddObserver(Observer* observer) OVERRIDE {
    DCHECK(thread_checker_.CalledOnValidThread());
    observers_.AddObserver(observer);
  }

  // IBusDaemonController override:
  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    DCHECK(thread_checker_.CalledOnValidThread());
    observers_.RemoveObserver(observer);
  }

  // IBusDaemonController override:
  virtual bool Start() OVERRIDE {
    DCHECK(thread_checker_.CalledOnValidThread());
    if (ibus_daemon_status_ == IBUS_DAEMON_RUNNING)
      return true;
    if (ibus_daemon_status_ == IBUS_DAEMON_STOP ||
        ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN) {
      return StartIBusDaemon();
    }
    return true;
  }

  // IBusDaemonController override:
  virtual bool Stop() OVERRIDE {
    DCHECK(thread_checker_.CalledOnValidThread());
    NOTREACHED() << "Termination of ibus-daemon is not supported"
                 << "http://crosbug.com/27051";
    return false;
  }

 private:
  // Starts ibus-daemon service.
  bool StartIBusDaemon() {
    if (ibus_daemon_status_ == IBUS_DAEMON_INITIALIZING ||
        ibus_daemon_status_ == IBUS_DAEMON_RUNNING) {
      DVLOG(1) << "MaybeLaunchIBusDaemon: ibus-daemon is already running.";
      return false;
    }

    ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING;
    ibus_daemon_address_ = base::StringPrintf(
        "unix:abstract=ibus-%d",
        base::RandInt(0, std::numeric_limits<int>::max()));

    scoped_ptr<base::Environment> env(base::Environment::Create());
    std::string address_file_path;
    env->GetVar("IBUS_ADDRESS_FILE", &address_file_path);
    DCHECK(!address_file_path.empty());

    // Set up ibus-daemon address file watcher before launching ibus-daemon,
    // because if watcher starts after ibus-daemon, we may miss the ibus
    // connection initialization.
    bool success = file_task_runner_->PostTaskAndReply(
        FROM_HERE,
        base::Bind(&StartWatch,
                   address_file_path,
                   base::Bind(&IBusDaemonControllerImpl::FilePathChanged,
                              weak_ptr_factory_.GetWeakPtr(),
                              ibus_daemon_address_),
                   ui_task_runner_),
        base::Bind(&IBusDaemonControllerImpl::LaunchIBusDaemon,
                   weak_ptr_factory_.GetWeakPtr(),
                   ibus_daemon_address_));
    DCHECK(success);
    return true;
  }

  // Launhes actual ibus-daemon process.
  void LaunchIBusDaemon(const std::string& ibus_address) {
    DCHECK(thread_checker_.CalledOnValidThread());
    DCHECK_EQ(base::kNullProcessHandle, process_handle_);
    static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
    // TODO(zork): Send output to /var/log/ibus.log
    std::vector<std::string> ibus_daemon_command_line;
    ibus_daemon_command_line.push_back(kIBusDaemonPath);
    ibus_daemon_command_line.push_back("--panel=disable");
    ibus_daemon_command_line.push_back("--cache=none");
    ibus_daemon_command_line.push_back("--restart");
    ibus_daemon_command_line.push_back("--replace");
    ibus_daemon_command_line.push_back("--address=" + ibus_address);

    if (!base::LaunchProcess(ibus_daemon_command_line,
                             base::LaunchOptions(),
                             &process_handle_)) {
      LOG(WARNING) << "Could not launch: "
                   << JoinString(ibus_daemon_command_line, " ");
    }
  }

  // Called by FilePathWatcher when the ibus-daemon address file is changed.
  // This function will be called on FILE thread.
  void FilePathChanged(const std::string& ibus_address) {
    ui_task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&IBusDaemonControllerImpl::IBusDaemonInitializationDone,
                   weak_ptr_factory_.GetWeakPtr(),
                   ibus_address));
  }

  // Called by FilePathChaged function, this function should be called on UI
  // thread.
  void IBusDaemonInitializationDone(const std::string& ibus_address) {
    if (ibus_daemon_address_ != ibus_address)
      return;

    if (ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) {
      // Stop() or OnIBusDaemonExit() has already been called.
      return;
    }

    DBusThreadManager::Get()->InitIBusBus(
        ibus_address,
        base::Bind(&IBusDaemonControllerImpl::OnIBusDaemonDisconnected,
                   weak_ptr_factory_.GetWeakPtr(),
                   base::GetProcId(process_handle_)));
    ibus_daemon_status_ = IBUS_DAEMON_RUNNING;
    FOR_EACH_OBSERVER(Observer, observers_, OnConnected());

    VLOG(1) << "The ibus-daemon initialization is done.";
  }

  // Called when the connection with ibus-daemon is disconnected.
  void OnIBusDaemonDisconnected(base::ProcessId pid) {
    if (!chromeos::DBusThreadManager::Get())
      return;  // Expected disconnection at shutting down. do nothing.

    if (process_handle_ != base::kNullProcessHandle) {
      if (base::GetProcId(process_handle_) == pid) {
        // ibus-daemon crashed.
        // TODO(nona): Shutdown ibus-bus connection.
        process_handle_ = base::kNullProcessHandle;
      } else {
        // This condition is as follows.
        // 1. Called Stop (process_handle_ becomes null)
        // 2. Called LaunchProcess (process_handle_ becomes new instance)
        // 3. Callbacked OnIBusDaemonExit for old instance and reach here.
        // In this case, we should not reset process_handle_ as null, and do not
        // re-launch ibus-daemon.
        return;
      }
    }

    const IBusDaemonStatus on_exit_state = ibus_daemon_status_;
    ibus_daemon_status_ = IBUS_DAEMON_STOP;
    FOR_EACH_OBSERVER(Observer, observers_, OnDisconnected());

    if (on_exit_state == IBUS_DAEMON_SHUTTING_DOWN)
      return;  // Normal exitting, so do nothing.

    LOG(ERROR) << "The ibus-daemon crashed. Re-launching...";
    StartIBusDaemon();
  }

  // The current ibus_daemon address. This value is assigned at the launching
  // ibus-daemon and used in bus connection initialization.
  std::string ibus_daemon_address_;

  // The process handle of the IBus daemon. kNullProcessHandle if it's not
  // running.
  base::ProcessHandle process_handle_;

  // Represents ibus-daemon's status.
  IBusDaemonStatus ibus_daemon_status_;

  // The task runner of UI thread.
  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;

  // The task runner of FILE thread.
  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;

  ObserverList<Observer> observers_;
  base::ThreadChecker thread_checker_;

  // Used for making callbacks for PostTask.
  base::WeakPtrFactory<IBusDaemonControllerImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(IBusDaemonControllerImpl);
};

// An implementation of IBusDaemonController without ibus-daemon interaction.
// Currently this class is used only on linux desktop.
// TODO(nona): Remove IBusDaemonControlelr this once crbug.com/171351 is fixed.
class IBusDaemonControllerDaemonlessImpl : public IBusDaemonController {
 public:
  IBusDaemonControllerDaemonlessImpl()
      : is_started_(false) {}
  virtual ~IBusDaemonControllerDaemonlessImpl() {}

  // IBusDaemonController overrides:
  virtual void AddObserver(Observer* observer) OVERRIDE {
    observers_.AddObserver(observer);
  }

  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    observers_.RemoveObserver(observer);
  }

  virtual bool Start() OVERRIDE {
    if (is_started_)
      return false;
    // IBusBus should be initialized but it is okay to pass "dummy address" as
    // the bus address because the actual dbus implementation is stub if the
    // Chrome OS is working on Linux desktop. This path is not used in
    // production at this moment, only for Chrome OS on Linux Desktop.
    // TODO(nona): Remove InitIBusBus oncer all legacy ime is migrated to IME
    // extension API.
    DBusThreadManager::Get()->InitIBusBus("dummy address",
                                          base::Bind(&base::DoNothing));
    is_started_ = true;
    FOR_EACH_OBSERVER(Observer, observers_, OnConnected());
    return true;
  }
  virtual bool Stop() OVERRIDE {
    if (!is_started_)
      return false;
    is_started_ = false;
    FOR_EACH_OBSERVER(Observer, observers_, OnDisconnected());
    return true;
  }

 private:
  ObserverList<Observer> observers_;
  bool is_started_;
  DISALLOW_COPY_AND_ASSIGN(IBusDaemonControllerDaemonlessImpl);
};

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// IBusDaemonController

IBusDaemonController::IBusDaemonController() {
}

IBusDaemonController::~IBusDaemonController() {
}

// static
void IBusDaemonController::Initialize(
    const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner) {
  DCHECK(g_ibus_daemon_controller == NULL)
      << "Do not call Initialize function multiple times.";
  g_ibus_daemon_controller = new IBusDaemonControllerDaemonlessImpl();
}

// static
void IBusDaemonController::InitializeForTesting(
    IBusDaemonController* controller) {
  DCHECK(g_ibus_daemon_controller == NULL);
  DCHECK(controller);
  g_ibus_daemon_controller = controller;
}

// static
void IBusDaemonController::Shutdown() {
  delete g_ibus_daemon_controller;
  g_ibus_daemon_controller = NULL;
}

// static
IBusDaemonController* IBusDaemonController::GetInstance() {
  return g_ibus_daemon_controller;
}

}  // namespace chromeos
