// 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 = "/var/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)
