// Copyright 2015 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 "lorgnette/epson_probe.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>

#include <map>
#include <string>
#include <unordered_set>

#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/stl_util.h>
#include <chromeos/dbus/service_constants.h>

#include "lorgnette/firewall_manager.h"

namespace lorgnette {

namespace epson_probe {

namespace {

const uint16_t kEpsonProbePort = 3289;
const char kEpsonDeviceNamePrefix[] = "epson2:net:";
const int kSyscallSuccess = 0;
const char kScannerManufacturerEpson[] = "Epson";
const char kScannerModelNetwork[] = "Network";
const char kScannerTypeFlatbed[] = "flatbed scanner";
const char kProbePacket[] = "EPSONP\0\xff\0\0\0\0\0\0\0";
const char kReplyPrefix[] = "EPSON";
const int kExpectedReplySize = 76;
const int kReplyWaitTimeSeconds = 1;

static_assert(sizeof(kReplyPrefix) < kExpectedReplySize,
              "Reply prefix should be smaller than the expected reply size");

}  // namespace

static bool GetTimeMonotonic(struct timeval* tv) {
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
    return false;
  }

  tv->tv_sec = ts.tv_sec;
  tv->tv_usec = ts.tv_nsec / 1000;
  return true;
}

static bool CreateBroadcastSocket(int* broadcast_socket, uint16_t* port) {
  int sock = HANDLE_EINTR(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
  if (sock < 0) {
    PLOG(ERROR) << "socket() returns " << sock;
    return false;
  }
  base::ScopedFD scoped_socket(sock);
  CHECK(sock < FD_SETSIZE);

  int result =
      HANDLE_EINTR(fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK));
  if (result < 0) {
    PLOG(ERROR) << "fcntl(NONBLOCK) returns " << result;
    return false;
  }

  struct sockaddr_in local;
  memset(&local, 0, sizeof(local));
  local.sin_family = AF_INET;
  local.sin_addr.s_addr = INADDR_ANY;
  result = HANDLE_EINTR(
      bind(sock, reinterpret_cast<struct sockaddr*>(&local), sizeof(local)));
  if (result != kSyscallSuccess) {
    PLOG(ERROR) << "bind() returns " << result;
    return false;
  }

  int broadcast_enable = 1;
  result =
      HANDLE_EINTR(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast_enable,
                              sizeof(broadcast_enable)));
  if (result != kSyscallSuccess) {
    PLOG(ERROR) << "setsockopt(SO_BROADCAST) returns " << result;
    return false;
  }

  socklen_t local_len = sizeof(local);
  result = HANDLE_EINTR(getsockname(
      sock, reinterpret_cast<struct sockaddr*>(&local), &local_len));
  if (result != kSyscallSuccess || local.sin_port == 0) {
    PLOG(ERROR) << "getsockname() returns " << result;
    return false;
  }

  *broadcast_socket = scoped_socket.release();
  *port = ntohs(local.sin_port);
  LOG(INFO) << "Bound to port " << ntohs(*port);

  return true;
}

static std::vector<ScannerInfo> SendProbeAndListen(uint16_t probe_socket) {
  std::vector<ScannerInfo> scanners;
  struct sockaddr_in broadcast;
  memset(&broadcast, 0, sizeof(broadcast));
  broadcast.sin_family = AF_INET;
  broadcast.sin_addr.s_addr = INADDR_BROADCAST;
  broadcast.sin_port = htons(kEpsonProbePort);
  int result = HANDLE_EINTR(sendto(
      probe_socket, kProbePacket, sizeof(kProbePacket), 0,
      reinterpret_cast<struct sockaddr*>(&broadcast), sizeof(broadcast)));
  if (result != sizeof(kProbePacket)) {
    LOG(ERROR) << "sendto() returns " << result << ": "
               << (result < 0 ? strerror(errno) : "");
    return scanners;
  }

  std::unordered_set<std::string> names;
  struct timeval maximum_wait_duration = {kReplyWaitTimeSeconds, 0};
  struct timeval now, end_time;
  CHECK(GetTimeMonotonic(&now));
  timeradd(&now, &maximum_wait_duration, &end_time);
  do {
    fd_set read_fds;
    FD_ZERO(&read_fds);
    FD_SET(probe_socket, &read_fds);

    struct timeval wait_duration;
    timersub(&end_time, &now, &wait_duration);
    result = HANDLE_EINTR(
        select(probe_socket + 1, &read_fds, nullptr, nullptr, &wait_duration));
    if (result < 0) {
      PLOG(ERROR) << "select() returns " << result;
      break;
    }

    if (result == 0) {
      break;
    }

    struct sockaddr_in remote;
    memset(&remote, 0, sizeof(remote));
    socklen_t remote_len = sizeof(remote);

    char response[kExpectedReplySize];
    result = HANDLE_EINTR(recvfrom(probe_socket, response, sizeof(response), 0,
                                   reinterpret_cast<struct sockaddr*>(&remote),
                                   &remote_len));
    if (result < 0) {
      PLOG(ERROR) << "recvfrom() returns " << result;
      break;
    }

    if (result == kExpectedReplySize &&
        memcmp(response, kReplyPrefix, sizeof(kReplyPrefix) - 1) == 0) {
      char* ip_address_string = inet_ntoa(remote.sin_addr);
      std::string device_name =
          std::string(kEpsonDeviceNamePrefix) + ip_address_string;

      if (names.count(device_name) == 0) {
        names.insert(device_name);
        // We don't use anything from the response; neither does sane-backends.
        ScannerInfo info;
        info.set_name(device_name);
        info.set_manufacturer(kScannerManufacturerEpson);
        info.set_model(kScannerModelNetwork);
        info.set_type(kScannerTypeFlatbed);
        scanners.push_back(info);
      } else {
        LOG(INFO) << "Not adding device " << device_name << "; already in list";
      }
    } else {
      LOG(ERROR) << "Unexpected reply; length was " << result;
    }

    CHECK(GetTimeMonotonic(&now));
  } while (timercmp(&now, &end_time, <));
  return scanners;
}

std::vector<ScannerInfo> ProbeForScanners(FirewallManager* firewall_manager) {
  int probe_socket;
  uint16_t local_port;
  if (!CreateBroadcastSocket(&probe_socket, &local_port)) {
    return std::vector<ScannerInfo>();
  }
  base::ScopedFD scoped_socket(probe_socket);
  PortToken token = firewall_manager->RequestUdpPortAccess(local_port);
  std::vector<ScannerInfo> scanners = SendProbeAndListen(probe_socket);
  return scanners;
}

}  // namespace epson_probe

}  // namespace lorgnette
