// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define _POSIX_C_SOURCE 200809L
#define _DARWIN_C_SOURCE
#define _GNU_SOURCE

#include "netprotocol.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <ifaddrs.h>
#include <lib/netboot/netboot.h>
#include <netinet/in.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>

uint16_t tftp_block_size = TFTP_DEFAULT_BLOCK_SZ;
uint16_t tftp_window_size = TFTP_DEFAULT_WINDOW_SZ;

static uint32_t cookie = 0x12345678;
static int netboot_timeout = 250;
static bool netboot_wait = true;

static struct timeval netboot_timeout_init(int msec) {
  struct timeval timeout_tv;
  timeout_tv.tv_sec = msec / 1000;
  timeout_tv.tv_usec = (msec % 1000) * 1000;

  struct timeval end_tv;
  gettimeofday(&end_tv, NULL);
  timeradd(&end_tv, &timeout_tv, &end_tv);

  return end_tv;
}

static int netboot_timeout_get_msec(const struct timeval* end_tv) {
  struct timeval wait_tv;
  struct timeval now_tv;
  gettimeofday(&now_tv, NULL);
  timersub(end_tv, &now_tv, &wait_tv);
  return wait_tv.tv_sec * 1000 + wait_tv.tv_usec / 1000;
}

static int netboot_bind_to_cmd_port(int socket) {
  struct sockaddr_in6 addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin6_family = AF_INET6;

  for (uint16_t port = NETBOOT_PORT_CMD_START; port <= NETBOOT_PORT_CMD_END; port++) {
    addr.sin6_port = htons(port);
    if (bind(socket, (void*)&addr, sizeof(addr)) == 0) {
      return 0;
    }
  }
  return -1;
}

static int netboot_send_query(int socket, unsigned port, const char* ifname) {
  const char* hostname = "*";
  size_t hostname_len = strlen(hostname) + 1;

  msg m;
  m.hdr.magic = NETBOOT_MAGIC;
  m.hdr.cookie = ++cookie;
  m.hdr.cmd = NETBOOT_COMMAND_QUERY;
  m.hdr.arg = 0;
  memcpy(m.data, hostname, hostname_len);

  struct sockaddr_in6 addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin6_family = AF_INET6;
  addr.sin6_port = htons(port);
  inet_pton(AF_INET6, "ff02::1", &addr.sin6_addr);

  struct ifaddrs* ifa;
  if (getifaddrs(&ifa) < 0) {
    fprintf(stderr, "error: cannot enumerate network interfaces\n");
    return -1;
  }

  bool success = false;

  struct ifaddrs* ifa_it = ifa;
  for (; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
    if (ifa_it->ifa_addr == NULL) {
      continue;
    }
    if (ifa_it->ifa_addr->sa_family != AF_INET6) {
      continue;
    }
    struct sockaddr_in6* in6 = (void*)ifa_it->ifa_addr;
    if (in6->sin6_scope_id == 0) {
      continue;
    }
    if (ifname && ifname[0] != 0 && strcmp(ifname, ifa_it->ifa_name)) {
      continue;
    }
    // printf("tx %s (sid=%d)\n", ifa_it->ifa_name, in6->sin6_scope_id);
    size_t sz = sizeof(netboot_message_header_t) + hostname_len;
    addr.sin6_scope_id = in6->sin6_scope_id;

    ssize_t r = sendto(socket, &m, sz, 0, (struct sockaddr*)&addr, sizeof(addr));
    if ((r >= 0) && (size_t)r == sz) {
      success = true;
    }
  }

  freeifaddrs(ifa);

  if (!success) {
    fprintf(stderr, "error: failed to find interface for sending query\n");
    return -1;
  }

  return 0;
}

static bool netboot_receive_query(int socket, on_device_cb callback, void* data) {
  struct sockaddr_in6 ra;
  socklen_t rlen = sizeof(ra);
  memset(&ra, 0, sizeof(ra));
  msg m;
  ssize_t r = recvfrom(socket, &m, sizeof(m), 0, (void*)&ra, &rlen);
  if (r < 0) {
    fprintf(stderr, "error: recvfrom: %s\n", strerror(errno));
  } else if ((size_t)r > sizeof(netboot_message_header_t)) {
    r -= sizeof(netboot_message_header_t);
    m.data[r] = 0;
    if ((m.hdr.magic == NETBOOT_MAGIC) && (m.hdr.cookie == cookie) &&
        (m.hdr.cmd == NETBOOT_COMMAND_ACK)) {
      char tmp[INET6_ADDRSTRLEN];
      if (inet_ntop(AF_INET6, &ra.sin6_addr, tmp, sizeof(tmp)) == NULL) {
        strcpy(tmp, "???");
      }
      // printf("found %s at %s/%d\n", (char*)m.data, tmp, ra.sin6_scope_id);
      if (strncmp("::", tmp, 2)) {
        device_info_t info;
        strncpy(info.nodename, (char*)m.data, sizeof(info.nodename));
        strncpy(info.inet6_addr_s, tmp, INET6_ADDRSTRLEN);
        memcpy(&info.inet6_addr, &ra, sizeof(ra));
        info.state = DEVICE;
        return callback(&info, data);
      }
    }
  }
  return false;
}

static struct option default_opts[] = {
    {"help", no_argument, NULL, 'h'},
    {"timeout", required_argument, NULL, 't'},
    {"nowait", no_argument, NULL, 'n'},
    {"block-size", required_argument, NULL, 'b'},
    {"window-size", required_argument, NULL, 'w'},
    {NULL, 0, NULL, 0},
};

static const struct option netboot_zero_opt = {NULL, 0, NULL, 0};

static size_t netboot_count_opts(const struct option* opts) {
  if (!opts) {
    return 0;
  }
  size_t count = 0;
  while (memcmp(&opts[count], &netboot_zero_opt, sizeof(netboot_zero_opt))) {
    count++;
  }
  return count;
}

static void netboot_copy_opts(struct option* dst_opts, const struct option* src_opts) {
  if (!src_opts) {
    return;
  }
  size_t i;
  for (i = 0; memcmp(&src_opts[i], &netboot_zero_opt, sizeof(netboot_zero_opt)); i++) {
    dst_opts[i] = src_opts[i];
  }
}

int netboot_handle_custom_getopt(int argc, char* const* argv, const struct option* custom_opts,
                                 bool (*opt_callback)(int ch, int argc, char* const* argv)) {
  size_t num_default_opts = netboot_count_opts(default_opts);
  size_t num_custom_opts = netboot_count_opts(custom_opts);

  struct option* combined_opts;
  combined_opts =
      (struct option*)malloc(sizeof(struct option) * (num_default_opts + num_custom_opts + 1));

  netboot_copy_opts(combined_opts, default_opts);
  netboot_copy_opts(combined_opts + num_default_opts, custom_opts);
  memset(&combined_opts[num_default_opts + num_custom_opts], 0x0, sizeof(struct option));

  int retval = -1;
  int ch;
  while ((ch = getopt_long_only(argc, argv, "t:", combined_opts, NULL)) != -1) {
    switch (ch) {
      case 't':
        netboot_timeout = atoi(optarg);
        break;
      case 'n':
        netboot_wait = false;
        break;
      case 'b':
        tftp_block_size = atoi(optarg);
        break;
      case 'w':
        tftp_window_size = atoi(optarg);
        break;
      default:
        if (opt_callback && opt_callback(ch, argc, argv)) {
          break;
        } else {
          goto err;
        }
    }
  }
  retval = optind;
err:
  free(combined_opts);
  return retval;
}

int netboot_handle_getopt(int argc, char* const* argv) {
  return netboot_handle_custom_getopt(argc, argv, NULL, NULL);
}

void netboot_usage(bool show_tftp_opts) {
  fprintf(stderr, "options:\n");
  fprintf(stderr, "    --help              Print this message.\n");
  fprintf(stderr, "    --timeout=<msec>    Set discovery timeout to <msec>.\n");
  fprintf(stderr, "    --nowait            Do not wait for first packet before timing out.\n");
  if (show_tftp_opts) {
    fprintf(stderr, "    --block-size=<sz>   Set tftp block size (default=%d).\n",
            TFTP_DEFAULT_BLOCK_SZ);
    fprintf(stderr, "    --window-size=<sz>  Set tftp window size (default=%d).\n",
            TFTP_DEFAULT_WINDOW_SZ);
  }
}

int netboot_discover(unsigned port, const char* ifname, on_device_cb callback, void* data) {
  if (!callback) {
    errno = EINVAL;
    return -1;
  }

  int s;
  if ((s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    fprintf(stderr, "error: cannot create socket: %s\n", strerror(errno));
    return -1;
  }

  if (netboot_bind_to_cmd_port(s) < 0) {
    fprintf(stderr, "error: cannot bind to command port: %s\n", strerror(errno));
    close(s);
    return -1;
  }

  if (netboot_send_query(s, port, ifname) < 0) {
    fprintf(stderr, "error: failed to send netboot query\n");
    close(s);
    return -1;
  }

  struct pollfd fds;
  fds.fd = s;
  fds.events = POLLIN;
  bool received_packets = false;
  bool first_wait = netboot_wait;

#if defined(__APPLE__)
  // macOS development hosts often have a firewall that prompts the user with a dialog box asking if
  // a conection should be allowed. On macOS, use a long timeout for the first wait to ensure the
  // user has a chance to read the dialog and respond. See also bug fxbug.dev/42296.
  //
  // TODO(maniscalco): Once macOS hosts are no longer supported for bringup development we can
  // remove this special case and the first_wait concept.
  struct timeval end_tv = netboot_timeout_init(first_wait ? 3600000 : netboot_timeout);
#else
  struct timeval end_tv = netboot_timeout_init(netboot_timeout);
#endif

  for (;;) {
    int wait_ms = netboot_timeout_get_msec(&end_tv);
    if (wait_ms < 0) {
      // Expired.
      break;
    }

    int r = poll(&fds, 1, wait_ms);
    if (r > 0 && (fds.revents & POLLIN)) {
      received_packets = true;
      if (!netboot_receive_query(s, callback, data)) {
        break;
      }
    } else if (r < 0 && errno != EAGAIN && errno != EINTR) {
      fprintf(stderr, "poll returned error: %s\n", strerror(errno));
      close(s);
      return -1;
    }
    if (first_wait) {
      end_tv = netboot_timeout_init(netboot_timeout);
      first_wait = 0;
    }
  }

  close(s);
  if (received_packets) {
    return 0;
  } else {
    errno = ETIMEDOUT;
    return -1;
  }
}

typedef struct netboot_open_cookie {
  struct sockaddr_in6 addr;
  const char* hostname;
  uint32_t index;
} netboot_open_cookie_t;

static bool netboot_open_callback(device_info_t* device, void* data) {
  netboot_open_cookie_t* cookie = data;
  cookie->index++;
  if (strcmp(cookie->hostname, "*") && strcmp(cookie->hostname, device->nodename)) {
    return true;
  }
  memcpy(&cookie->addr, &device->inet6_addr, sizeof(device->inet6_addr));
  return false;
}

int netboot_open(const char* hostname, const char* ifname, struct sockaddr_in6* addr,
                 bool make_connection) {
  if ((hostname == NULL) || (hostname[0] == 0)) {
    char* envname = getenv("ZIRCON_NODENAME");
    hostname = envname && envname[0] != 0 ? envname : "*";
  }
  size_t hostname_len = strlen(hostname) + 1;
  if (hostname_len > MAXSIZE) {
    errno = EINVAL;
    return -1;
  }

  netboot_open_cookie_t cookie;
  socklen_t rlen = sizeof(cookie.addr);
  memset(&(cookie.addr), 0, sizeof(cookie.addr));
  cookie.index = 0;
  cookie.hostname = hostname;
  if (netboot_discover(NETBOOT_PORT_SERVER, ifname, netboot_open_callback, &cookie) < 0) {
    return -1;
  }
  // Device not found
  if (cookie.index == 0) {
    errno = EINVAL;
    return -1;
  }

  int s;
  if ((s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    fprintf(stderr, "error: cannot create socket: %s\n", strerror(errno));
    return -1;
  }

  if (netboot_bind_to_cmd_port(s) < 0) {
    fprintf(stderr, "cannot bind to command port: %s\n", strerror(errno));
    return -1;
  }

  struct timeval tv;
  tv.tv_sec = 0;
  tv.tv_usec = 250 * 1000;
  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

  if (addr) {
    memcpy(addr, &cookie.addr, sizeof(cookie.addr));
  }

  if (make_connection && connect(s, (void*)&cookie.addr, rlen) < 0) {
    fprintf(stderr, "error: cannot connect UDP port\n");
    close(s);
    return -1;
  }
  return s;
}
