// 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 "modemfwd/daemon.h"

#include <sysexits.h>

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

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>

#include "modemfwd/firmware_directory.h"
#include "modemfwd/logging.h"
#include "modemfwd/modem.h"
#include "modemfwd/modem_flasher.h"
#include "modemfwd/modem_helper_directory.h"
#include "modemfwd/modem_tracker.h"

namespace {

std::string ToOnOffString(bool b) {
  return b ? "on" : "off";
}

}  // namespace

namespace modemfwd {

DBusAdaptor::DBusAdaptor(scoped_refptr<dbus::Bus> bus, Daemon* daemon)
    : org::chromium::ModemfwdAdaptor(this),
      dbus_object_(nullptr, bus, dbus::ObjectPath(kModemfwdServicePath)),
      daemon_(daemon) {
  DCHECK(daemon);
}

void DBusAdaptor::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
  RegisterWithDBusObject(&dbus_object_);
  dbus_object_.RegisterAsync(cb);
}

void DBusAdaptor::SetDebugMode(bool debug_mode) {
  g_extra_logging = debug_mode;
  LOG(INFO) << "Debug mode is now " << ToOnOffString(ELOG_IS_ON());
}

bool DBusAdaptor::ForceFlash(const std::string& device_id) {
  return daemon_->ForceFlash(device_id);
}

Daemon::Daemon(const std::string& journal_file,
               const std::string& helper_directory)
    : Daemon(journal_file, helper_directory, "") {}

Daemon::Daemon(const std::string& journal_file,
               const std::string& helper_directory,
               const std::string& firmware_directory)
    : DBusServiceDaemon(kModemfwdServiceName),
      journal_file_path_(journal_file),
      helper_dir_path_(helper_directory),
      firmware_dir_path_(firmware_directory),
      weak_ptr_factory_(this) {}

int Daemon::OnInit() {
  int exit_code = brillo::DBusServiceDaemon::OnInit();
  if (exit_code != EX_OK)
    return exit_code;
  DCHECK(!helper_dir_path_.empty());

  if (!base::DirectoryExists(helper_dir_path_)) {
    LOG(ERROR) << "Supplied modem-specific helper directory "
               << helper_dir_path_.value() << " does not exist";
    return EX_UNAVAILABLE;
  }

  helper_directory_ = CreateModemHelperDirectory(helper_dir_path_);
  if (!helper_directory_) {
    LOG(ERROR) << "No suitable helpers found in " << helper_dir_path_.value();
    return EX_UNAVAILABLE;
  }

  // If no firmware directory was supplied, we can't run yet. This will
  // change when we get DLC functionality.
  if (firmware_dir_path_.empty())
    return EX_UNAVAILABLE;

  if (!base::DirectoryExists(firmware_dir_path_)) {
    LOG(ERROR) << "Supplied firmware directory " << firmware_dir_path_.value()
               << " does not exist";
    return EX_UNAVAILABLE;
  }

  return CompleteInitialization();
}

int Daemon::CompleteInitialization() {
  CHECK(!firmware_dir_path_.empty());

  auto firmware_directory = CreateFirmwareDirectory(firmware_dir_path_);
  if (!firmware_directory) {
    LOG(ERROR) << "Could not load firmware directory (bad manifest?)";
    return EX_UNAVAILABLE;
  }

  auto journal = OpenJournal(journal_file_path_, firmware_directory.get(),
                             helper_directory_.get());
  if (!journal) {
    LOG(ERROR) << "Could not open journal file";
    return EX_UNAVAILABLE;
  }

  modem_flasher_ = std::make_unique<modemfwd::ModemFlasher>(
      std::move(firmware_directory), std::move(journal));

  modem_tracker_ = std::make_unique<modemfwd::ModemTracker>(
      bus_,
      base::Bind(&Daemon::OnModemAppeared, weak_ptr_factory_.GetWeakPtr()));

  return EX_OK;
}

int Daemon::OnEventLoopStarted() {
  // Stub until DLC service is implemented.
  return EX_OK;
}

void Daemon::OnModemAppeared(
    std::unique_ptr<org::chromium::flimflam::DeviceProxy> device) {
  auto modem = CreateModem(std::move(device), helper_directory_.get());
  if (!modem)
    return;

  std::string equipment_id = modem->GetEquipmentId();
  ELOG(INFO) << "Modem appeared with equipment ID \"" << equipment_id << "\"";
  if (modem_reappear_callbacks_.count(equipment_id) > 0) {
    modem_reappear_callbacks_[equipment_id].Run();
    modem_reappear_callbacks_.erase(equipment_id);
  }

  base::Closure cb = modem_flasher_->TryFlash(modem.get());
  if (!cb.is_null())
    modem_reappear_callbacks_[equipment_id] = cb;
}

void Daemon::RegisterDBusObjectsAsync(
    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
  dbus_adaptor_.reset(new DBusAdaptor(bus_, this));
  dbus_adaptor_->RegisterAsync(
      sequencer->GetHandler("RegisterAsync() failed", true));
}

bool Daemon::ForceFlash(const std::string& device_id) {
  auto stub_modem = CreateStubModem(device_id, helper_directory_.get());
  if (!stub_modem)
    return false;

  ELOG(INFO) << "Force-flashing modem with device ID [" << device_id << "]";
  base::Closure cb = modem_flasher_->TryFlash(stub_modem.get());
  // We don't know the equipment ID of this modem, and if we're force-flashing
  // then we probably already have a problem with the modem coming up, so
  // cleaning up at this point is not a problem. Run the callback now if we
  // got one.
  if (!cb.is_null())
    cb.Run();
  return !cb.is_null();
}

}  // namespace modemfwd
