// 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.

#include "netsvc.h"

#include <fcntl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/zx/clock.h>
#include <unistd.h>
#include <zircon/boot/netboot.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <string>

#include <fbl/unique_fd.h>
#include <inet6/inet6.h>
#include <inet6/netifc.h>

#include "args.h"
#include "debuglog.h"
#include "netboot.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"
#include "tftp.h"

#ifndef ENABLE_SLAAC
// SLAAC RA's are disabled by default as they intefere with tests in environments where there are
// many devices on the same LAN.
#define ENABLE_SLAAC 0
#endif

static bool g_netbootloader = false;

// When false (default), will only respond to a limited number of commands.
// Currently, NB_QUERY (to support netls and netaddr), as well as responding to
// ICMP as usual.
static bool g_all_features = false;

static char g_nodename[HOST_NAME_MAX];

bool netbootloader() { return g_netbootloader; }
bool all_features() { return g_all_features; }
const char* nodename() { return g_nodename; }

void udp6_recv(void* data, size_t len, const ip6_addr_t* daddr, uint16_t dport,
               const ip6_addr_t* saddr, uint16_t sport) {
  bool mcast = (memcmp(daddr, &ip6_ll_all_nodes, sizeof(ip6_addr_t)) == 0);

  if (!all_features()) {
    if (dport != NB_SERVER_PORT) {
      // Only some netboot commands allowed in limited mode.
      return;
    }
  }

  switch (dport) {
    case NB_SERVER_PORT:
      netboot_recv(data, len, mcast, daddr, dport, saddr, sport);
      break;
    case DEBUGLOG_ACK_PORT:
      debuglog_recv(data, len, mcast);
      break;
    case NB_TFTP_INCOMING_PORT:
    case NB_TFTP_OUTGOING_PORT:
      tftp_recv(data, len, daddr, dport, saddr, sport);
      break;
  }
}

void netifc_recv(void* data, size_t len) { eth_recv(data, len); }

bool netifc_send_pending() {
  if (!tftp_has_pending()) {
    return false;
  }
  tftp_send_next();
  return tftp_has_pending();
}

static const char* zedboot_banner =
    "              _ _                 _   \n"
    "             | | |               | |  \n"
    "  _______  __| | |__   ___   ___ | |_ \n"
    " |_  / _ \\/ _` | '_ \\ / _ \\ / _ \\| __|\n"
    "  / /  __/ (_| | |_) | (_) | (_) | |_ \n"
    " /___\\___|\\__,_|_.__/ \\___/ \\___/ \\__|\n"
    "                                      \n"
    "\n";

int main(int argc, char** argv) {
  zx_status_t status = StdoutToDebuglog::Init();
  if (status != ZX_OK) {
    printf("Failed to redirect stdout to debuglog, assuming test environment and continuing\n");
  }

  fbl::unique_fd svc_root(open("/svc", O_RDWR | O_DIRECTORY));
  fdio_cpp::UnownedFdioCaller caller(svc_root.get());

  NetsvcArgs args;
  const char* error;
  if (ParseArgs(argc, argv, caller.directory(), &error, &args) < 0) {
    printf("netsvc: fatal error: %s\n", error);
    return -1;
  };
  if (args.disable) {
    printf("netsvc: Disabled. Exiting.\n");
    return 0;
  }

  bool print_nodename_and_exit = args.print_nodename_and_exit;
  bool should_advertise = args.advertise;
  g_netbootloader = args.netboot;
  g_all_features = args.all_features;
  const char* interface = args.interface.empty() ? nullptr : args.interface.c_str();

  if (g_netbootloader && !g_all_features) {
    printf("netsvc: fatal: --netboot requires --all-features\n");
    return -1;
  }

  if (g_all_features) {
    if (debuglog_init() < 0) {
      return -1;
    }
  }

  printf("netsvc: running in %s mode\n", g_all_features ? "full" : "limited");

  gethostname(g_nodename, sizeof(g_nodename));

  printf("netsvc: nodename='%s'\n", g_nodename);

  if (print_nodename_and_exit) {
    return 0;
  }

  if (interface != nullptr) {
    printf("netsvc: looking for interface %s\n", interface);
  }

  if (!should_advertise) {
    printf("netsvc: will not advertise\n");
  }

  for (;;) {
    if (netifc_open(interface) != 0) {
      printf("netsvc: fatal error initializing network\n");
      return -1;
    }

    if (g_netbootloader) {
      printf("%szedboot: version: %s\n\n", zedboot_banner, BOOTLOADER_VERSION);
    }

    printf("netsvc: start\n");

    zx_time_t advertise_next_timeout = ZX_TIME_INFINITE;
    if (g_netbootloader && should_advertise) {
      advertise_next_timeout = zx::clock::get_monotonic().get();
    }

    for (;;) {
      if (netifc_poll(
              std::min({advertise_next_timeout, debuglog_next_timeout(), tftp_next_timeout()}))) {
        printf("netsvc: netifc_poll() failed - terminating\n");
        break;
      }

      zx_time_t now = zx::clock::get_monotonic().get();
      if (now > advertise_next_timeout) {
#if ENABLE_SLAAC
        send_router_advertisement();
#endif
        netboot_advertise(g_nodename);
        advertise_next_timeout = zx_deadline_after(ZX_SEC(1));
      }
      if (now > debuglog_next_timeout()) {
        debuglog_timeout_expired();
      }
      if (now > tftp_next_timeout()) {
        tftp_timeout_expired();
      }
    }
    netifc_close();
  }
}
