// Copyright 2015 The Weave 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 "examples/provider/wifi_manager.h"

#include <arpa/inet.h>
#include <linux/wireless.h>
#include <sys/ioctl.h>
#include <sys/wait.h>

#include <fstream>

#include <base/bind.h>
#include <weave/provider/task_runner.h>

#include "examples/provider/event_network.h"
#include "examples/provider/ssl_stream.h"

namespace weave {
namespace examples {

namespace {

int ForkCmd(const std::string& path, const std::vector<std::string>& args) {
  int pid = fork();
  if (pid != 0)
    return pid;

  std::vector<const char*> args_vector;
  args_vector.push_back(path.c_str());
  for (auto& i : args)
    args_vector.push_back(i.c_str());
  args_vector.push_back(nullptr);

  execvp(path.c_str(), const_cast<char**>(args_vector.data()));
  NOTREACHED();
  return 0;
}

}  // namespace

WifiImpl::WifiImpl(provider::TaskRunner* task_runner, EventNetworkImpl* network)
    : task_runner_{task_runner}, network_{network} {
  CHECK_EQ(0u, getuid())
      << "WiFi manager expects root access to control WiFi capabilities";
  StopAccessPoint();
}
WifiImpl::~WifiImpl() {
  StopAccessPoint();
}

void WifiImpl::TryToConnect(const std::string& ssid,
                            const std::string& passphrase,
                            int pid,
                            base::Time until,
                            const DoneCallback& callback) {
  if (pid) {
    int status = 0;
    if (pid == waitpid(pid, &status, WNOWAIT)) {
      int sockf_d = socket(AF_INET, SOCK_DGRAM, 0);
      CHECK_GE(sockf_d, 0) << strerror(errno);

      iwreq wreq = {};
      snprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "wlan0");
      std::string essid(' ', IW_ESSID_MAX_SIZE + 1);
      wreq.u.essid.pointer = &essid[0];
      wreq.u.essid.length = essid.size();
      CHECK_GE(ioctl(sockf_d, SIOCGIWESSID, &wreq), 0) << strerror(errno);
      essid.resize(wreq.u.essid.length);
      close(sockf_d);

      if (ssid == essid)
        return task_runner_->PostDelayedTask(FROM_HERE,
                                             base::Bind(callback, nullptr), {});
      pid = 0;  // Try again.
    }
  }

  if (pid == 0) {
    pid = ForkCmd("nmcli",
                  {"dev", "wifi", "connect", ssid, "password", passphrase});
  }

  if (base::Time::Now() >= until) {
    ErrorPtr error;
    Error::AddTo(&error, FROM_HERE, "timeout",
                 "Timeout connecting to WiFI network.");
    task_runner_->PostDelayedTask(
        FROM_HERE, base::Bind(callback, base::Passed(&error)), {});
    return;
  }

  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&WifiImpl::TryToConnect, weak_ptr_factory_.GetWeakPtr(), ssid,
                 passphrase, pid, until, callback),
      base::TimeDelta::FromSeconds(1));
}

void WifiImpl::Connect(const std::string& ssid,
                       const std::string& passphrase,
                       const DoneCallback& callback) {
  network_->SetSimulateOffline(false);
  CHECK(!hostapd_started_);
  if (hostapd_started_) {
    ErrorPtr error;
    Error::AddTo(&error, FROM_HERE, "busy", "Running Access Point.");
    task_runner_->PostDelayedTask(
        FROM_HERE, base::Bind(callback, base::Passed(&error)), {});
    return;
  }

  TryToConnect(ssid, passphrase, 0,
               base::Time::Now() + base::TimeDelta::FromMinutes(1), callback);
}

void WifiImpl::StartAccessPoint(const std::string& ssid) {
  if (hostapd_started_)
    return;

  // Release wlan0 interface.
  CHECK_EQ(0, std::system("nmcli nm wifi off"));
  CHECK_EQ(0, std::system("rfkill unblock wlan"));
  sleep(1);

  std::string hostapd_conf = "/tmp/weave_hostapd.conf";
  {
    std::ofstream ofs(hostapd_conf);
    ofs << "interface=wlan0" << std::endl;
    ofs << "channel=1" << std::endl;
    ofs << "ssid=" << ssid << std::endl;
  }

  CHECK_EQ(0, std::system(("hostapd -B -K " + hostapd_conf).c_str()));
  hostapd_started_ = true;

  for (size_t i = 0; i < 10; ++i) {
    if (0 == std::system("ifconfig wlan0 192.168.76.1/24"))
      break;
    sleep(1);
  }

  std::string dnsmasq_conf = "/tmp/weave_dnsmasq.conf";
  {
    std::ofstream ofs(dnsmasq_conf.c_str());
    ofs << "port=0" << std::endl;
    ofs << "bind-interfaces" << std::endl;
    ofs << "log-dhcp" << std::endl;
    ofs << "dhcp-range=192.168.76.10,192.168.76.100" << std::endl;
    ofs << "interface=wlan0" << std::endl;
    ofs << "dhcp-leasefile=" << dnsmasq_conf << ".leases" << std::endl;
  }

  CHECK_EQ(0, std::system(("dnsmasq --conf-file=" + dnsmasq_conf).c_str()));
}

void WifiImpl::StopAccessPoint() {
  base::IgnoreResult(std::system("pkill -f dnsmasq.*/tmp/weave"));
  base::IgnoreResult(std::system("pkill -f hostapd.*/tmp/weave"));
  CHECK_EQ(0, std::system("nmcli nm wifi on"));
  hostapd_started_ = false;
}

bool WifiImpl::HasWifiCapability() {
  return std::system("nmcli dev | grep ^wlan0") == 0;
}

}  // namespace examples
}  // namespace weave
