// Copyright 2014 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 <base/check_op.h>
#include <brillo/daemons/daemon.h>

#include <signal.h>
#include <sysexits.h>
#include <time.h>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/run_loop.h>

namespace brillo {

Daemon::Daemon() : exit_code_{EX_OK}, exiting_(false) {
  message_loop_.SetAsCurrent();
}

Daemon::~Daemon() {}

int Daemon::Run() {
  int exit_code = OnInit();
  if (exit_code != EX_OK)
    return exit_code;

  message_loop_.PostTask(
      base::BindOnce(&Daemon::OnEventLoopStartedTask, base::Unretained(this)));
  message_loop_.Run();

  OnShutdown(&exit_code_);

  // base::RunLoop::QuitClosure() causes the message loop to quit
  // immediately, even if pending tasks are still queued.
  // Run a secondary loop to make sure all those are processed.
  // This becomes important when working with D-Bus since dbus::Bus does
  // a bunch of clean-up tasks asynchronously when shutting down.
  while (message_loop_.RunOnce(false /* may_block */)) {
  }

  return exit_code_;
}

void Daemon::Quit() {
  QuitWithExitCode(EX_OK);
}

void Daemon::QuitWithExitCode(int exit_code) {
  exit_code_ = exit_code;
  message_loop_.PostTask(FROM_HERE, QuitClosure());
}

void Daemon::RegisterHandler(
    int signal,
    const AsynchronousSignalHandlerInterface::SignalHandler& callback) {
  async_signal_handler_.RegisterHandler(signal, callback);
}

void Daemon::UnregisterHandler(int signal) {
  async_signal_handler_.UnregisterHandler(signal);
}

int Daemon::OnInit() {
  async_signal_handler_.Init();
  for (int signal : {SIGTERM, SIGINT}) {
    async_signal_handler_.RegisterHandler(
        signal, base::Bind(&Daemon::Shutdown, base::Unretained(this)));
  }
  async_signal_handler_.RegisterHandler(
      SIGHUP, base::Bind(&Daemon::Restart, base::Unretained(this)));
  return EX_OK;
}

int Daemon::OnEventLoopStarted() {
  // Do nothing.
  return EX_OK;
}

void Daemon::OnShutdown(int* /* exit_code */) {
  // Do nothing.
}

bool Daemon::OnRestart() {
  // Not handled.
  return false;  // Returning false will shut down the daemon instead.
}

bool Daemon::Shutdown(const signalfd_siginfo& /* info */) {
  // Only respond to the first call.
  if (!exiting_) {
    exiting_ = true;
    Quit();
  }
  // Always return false, to avoid unregistering the signal handler. We might
  // receive multiple successive signals, and we don't want to take the default
  // response (termination) while we're still tearing down.
  return false;
}

bool Daemon::Restart(const signalfd_siginfo& /* info */) {
  if (!exiting_ && !OnRestart()) {
    // Only Quit() once.
    exiting_ = true;
    Quit();
  }
  // Always return false, to avoid unregistering the signal handler. We might
  // receive multiple successive signals, and we don't want to take the default
  // response (termination) while we're still tearing down.
  return false;
}

void Daemon::OnEventLoopStartedTask() {
  int exit_code = OnEventLoopStarted();
  if (exit_code != EX_OK)
    QuitWithExitCode(exit_code);
}

void UpdateLogSymlinks(const base::FilePath& latest_log_symlink,
                       const base::FilePath& previous_log_symlink,
                       const base::FilePath& log_file) {
  base::DeleteFile(previous_log_symlink);
  base::Move(latest_log_symlink, previous_log_symlink);
  if (!base::CreateSymbolicLink(log_file.BaseName(), latest_log_symlink)) {
    PLOG(ERROR) << "Unable to create symbolic link from "
                << latest_log_symlink.value() << " to " << log_file.value();
  }
}

std::string GetTimeAsLogString(const base::Time& time) {
  time_t utime = time.ToTimeT();
  struct tm tm;
  CHECK_EQ(localtime_r(&utime, &tm), &tm);
  char str[16];
  CHECK_EQ(strftime(str, sizeof(str), "%Y%m%d-%H%M%S", &tm), 15UL);
  return std::string(str);
}

}  // namespace brillo
