// Copyright (c) 2010 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 "gobi-cromo-plugin/gobi_modem_handler.h"

#include <glib.h>
extern "C" {
#include <libudev.h>
#include <stdio.h>
#include <syslog.h>
// Defines from syslog.h that conflict with base/logging.h. Ugh.
#undef LOG_INFO
#undef LOG_WARNING
}

#include <base/logging.h>
#include <cromo/cromo_server.h>
#include <cromo/plugin.h>

#include "gobi-cromo-plugin/device_watcher.h"
#include "gobi-cromo-plugin/gobi_cdma_modem.h"
#include "gobi-cromo-plugin/gobi_modem.h"
#include "gobi-cromo-plugin/gobi_modem_factory.h"
#include "gobi-cromo-plugin/gobi_sdk_wrapper.h"

#ifndef VCSID
#define VCSID "<not set>"
#endif

using std::vector;

static ModemHandler* mm;

static const int kDevicePollIntervalSecs = 1;
static const char* kQCDeviceName = "QCQMI";
static const char* kUSBDeviceListFile = "/run/cromo/usb-devices";

static void udev_callback(void* data, const char *action, const char *device) {
  GobiModemHandler* handler = static_cast<GobiModemHandler*>(data);
  handler->HandleUdevMessage(action, device);
}

static void timeout_callback(void* data) {
  GobiModemHandler* handler = static_cast<GobiModemHandler*>(data);
  handler->HandlePollEvent();
}

GobiModemHandler::GobiModemHandler(CromoServer& server)
    : ModemHandler(server, "Gobi"),
      clear_device_list_on_destroy_(true),
      device_watcher_(nullptr),
      scan_generation_(0) {
}

GobiModemHandler::~GobiModemHandler() {
  if (clear_device_list_on_destroy_) {
    ClearDeviceListFile();
  }
  delete device_watcher_;
}

bool GobiModemHandler::Initialize() {
  // Can't use LOG here: we want this to be always logged, but we don't want it
  // to be an error. Fortunately syslog declares both openlog() and closelog()
  // 'optional', so...
  syslog(LOG_NOTICE, "gobi-cromo-plugin vcsid %s", VCSID);
  sdk_.reset(new gobi::Sdk(GobiModem::SinkSdkError));
  sdk_->Init();
  GobiModem::set_handler(this);
  MonitorDevices();
  RegisterSelf();
  return true;
}

// Watch for addition and removal of Gobi devices.
// When a udev event arrives, we begin polling
// the SDK until the change reported by the
// event is visible via EnumerateDevices. At that
// point, we stop polling.
void GobiModemHandler::MonitorDevices() {
  device_watcher_ = new DeviceWatcher(kQCDeviceName);
  device_watcher_->set_callback(udev_callback, this);
  device_watcher_->StartMonitoring();
  GetDeviceList();
}

void GobiModemHandler::HandleUdevMessage(const char *action,
                                         const char *device) {
  // udev deals in long device names (like "/dev/qcqmi0") but the qualcomm sdk
  // deals in just basenames (like "qcqmi0"). The control paths we store in the
  // control-path-to-device map are basenames, so only use the device's basename
  // here.
  if (strstr(device, "/dev/") == device)
    device += strlen("/dev/");

  // If this method is called due to an udev event after the poller is started
  // but before the polling callback is invoked, the GetDeviceList() call below
  // may potentially "absorb" any changes in the device list, which means the
  // GetDeviceList() call in the polling callback will return false and keep the
  // polling continuously running. Thus, we stop any scheduled polling here to
  // prevent that from happening.
  device_watcher_->StopPolling();

  bool saw_changes = GetDeviceList();
  if (0 == strcmp("change", action)) {
    // No need to start poller as there is no device added or removed.
    // Otherwise, if we start the poller, it won't be stopped as
    // GetDeviceList() will return false.
    return;
  }

  if (0 == strcmp("add" , action) && DevicePresentByControlPath(device)) {
    LOG(INFO) << "Device already present";
    return;    // Do not start poller
  }

  if (0 == strcmp("remove", action)) {
    // No need to start poller; we have acted on event
    RemoveDeviceByControlPath(device);
    return;
  }

  if (!saw_changes) {
    // The udev change isn't yet visible to QCWWAN.  Poll until it is.
    device_watcher_->StartPolling(kDevicePollIntervalSecs,
                                  timeout_callback,
                                  this);
  } else {
    LOG(ERROR) << "Saw unexpected change " << action << " " << device;
  }
}

void GobiModemHandler::RemoveDeviceByControlPath(const char *path) {
  ControlPathToModem::iterator p = control_path_to_modem_.find(path);
  if (p != control_path_to_modem_.end()) {
    LOG(INFO) << "Removing device " << path;
    RemoveDeviceByIterator(p);
  } else {
    LOG(INFO) << "Could not find " << path << " to remove";
  }
}

static gboolean delete_modem(gpointer p) {
  GobiModem *m = static_cast<GobiModem*>(p);
  delete m;
  return FALSE;
}

static gboolean clear_idle_callbacks_and_delete(gpointer p) {
  GobiModem *m = static_cast<GobiModem*>(p);
  m->ClearIdleCallbacks();
  g_idle_add(delete_modem, m);
  return FALSE;
}

GobiModemHandler::ControlPathToModem::iterator
GobiModemHandler::RemoveDeviceByIterator(ControlPathToModem::iterator p) {
  if (p == control_path_to_modem_.end()) {
    LOG(ERROR) << "Bad iterator";
    return p;
  }
  ControlPathToModem::iterator next = p;
  ++next;

  GobiModem *m = p->second;
  if (!m) {
    LOG(ERROR) << "no modem";
    return next;
  }
  server().DeviceRemoved(m->path());
  control_path_to_modem_.erase(p);
  g_idle_add(clear_idle_callbacks_and_delete, m);
  return next;
}

void GobiModemHandler::Remove(GobiModem* modem) {
  for (ControlPathToModem::iterator p = key_to_modem_.begin();
       p != key_to_modem_.end(); ++p) {
    GobiModem* m = p->second;
    if (m == modem) {
      RemoveDeviceByIterator(p);
    }
  }
}


bool GobiModemHandler::DevicePresentByControlPath(const char *path) {
  return control_path_to_modem_.find(path) != control_path_to_modem_.end();
}

void GobiModemHandler::HandlePollEvent() {
  if (GetDeviceList())
    device_watcher_->StopPolling();
}

// Get the list of visible devices, keeping track of what devices have
// been added and removed since the last time we looked. Returns true
// if any devices have been added or removed, false otherwise.
bool GobiModemHandler::GetDeviceList() {
  const int MAX_MODEMS = 16;
  ULONG rc;

  gobi::DeviceElement devices[MAX_MODEMS];
  BYTE num_devices = MAX_MODEMS;

  rc = sdk_->QCWWANEnumerateDevices(&num_devices,
                                    reinterpret_cast<BYTE*>(devices));
  if (rc != 0) {
    LOG(ERROR) << "QCWWANEnumerateDevices returned " << rc;
    return false;
  }

  ++scan_generation_;
  bool something_changed = false;

  LOG(INFO) << "QCWWANEnumerateDevices found " << static_cast<int>(num_devices)
            << " device(s)";
  for (size_t i = 0; i < num_devices; ++i) {
    ControlPathToModem::iterator p =
        control_path_to_modem_.find(devices[i].deviceNode);
    if (p != control_path_to_modem_.end()) {
      CHECK((*p).second);
      (*p).second->set_last_seen(scan_generation_);
    } else {
      something_changed = true;
      GobiModem* m = GobiModemFactory::CreateModem(server().conn(),
                                                   MakePath(),
                                                   devices[i],
                                                   sdk_.get());
      if (!m) {
        LOG(ERROR) << "Could not create modem object for "
                   << devices[i].deviceNode;
        continue;
      }
      m->Init();
      m->set_last_seen(scan_generation_);
      control_path_to_modem_[std::string(devices[i].deviceNode)] = m;
      server().DeviceAdded(m->path());
      LOG(INFO) << "Found new modem: " << m->path()
                << " (" << devices[i].deviceNode << ")";
    }
  }

  for (ControlPathToModem::iterator p = control_path_to_modem_.begin();
       p != control_path_to_modem_.end(); ) {
    GobiModem* m = p->second;
    if (m->last_seen() != scan_generation_) {
      something_changed = true;
      LOG(INFO) << "Device " << m->path() << " has disappeared";
      p = RemoveDeviceByIterator(p);
    } else {
      ++p;
    }
  }

  WriteDeviceListFile(control_path_to_modem_);

  return something_changed;
}

void GobiModemHandler::ClearDeviceListFile() {
  ControlPathToModem no_modems;
  WriteDeviceListFile(no_modems);
}

void GobiModemHandler::WriteDeviceListFile(const ControlPathToModem &modems) {
  FILE *dev_list_file = fopen(kUSBDeviceListFile, "w");
  if (dev_list_file) {
    for (ControlPathToModem::const_iterator p = modems.begin();
         p != modems.end(); p++) {
      GobiModem *m = p->second;
      fprintf(dev_list_file, "%s\n", m->GetUSBAddress().c_str());
    }
    fclose(dev_list_file);
  }
}

// Enumerate the existing devices, and add them to the list of devices
// that are managed by the ChromeOS modem manager

vector<DBus::Path> GobiModemHandler::EnumerateDevices(DBus::Error& error) {
  vector <DBus::Path> to_return;
  for (ControlPathToModem::iterator p = control_path_to_modem_.begin();
       p != control_path_to_modem_.end(); ++p) {
    to_return.push_back(p->second->path());
  }
  return to_return;
}

GobiModem* GobiModemHandler::LookupByDbusPath(const std::string& dbuspath) {
  for (ControlPathToModem::iterator p = control_path_to_modem_.begin();
       p != control_path_to_modem_.end(); ++p) {
    GobiModem* m = p->second;
    if (m->path() == dbuspath)
      return m;
  }
  return nullptr;
}

void GobiModemHandler::ExitLeavingModemsForCleanup() {
  clear_device_list_on_destroy_ = false;
  LOG(ERROR) << "Exiting without clearing device list.";
  // Send a SIGTERM so cromo gets a chance to clean up before exiting.
  kill(getpid(), SIGTERM);
}

static void onload(CromoServer* server) {
  mm = new GobiModemHandler(*server);
  if (!mm->Initialize())
    LOG(ERROR) << "Failed to initialize GobiModemHandler";
}

static void onunload() {
  delete mm;
}

CROMO_DEFINE_PLUGIN(gobi, onload, onunload)
