// Copyright 2019 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 <fcntl.h>
#include <fuchsia/device/c/fidl.h>
#include <fuchsia/device/llcpp/fidl.h>
#include <fuchsia/hardware/ethernet/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/watcher.h>
#include <stdio.h>
#include <string.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>

#include <inet6/netifc-discover.h>

typedef struct netifc_cb_ctx {
  const char* dirname;
  zx_handle_t* interface;
  const char* topological_path;
  uint8_t netmac[6];
  uint16_t netmtu;
} netifc_cb_ctx_t;

static zx_status_t netifc_open_cb(int dirfd, int event, const char* filename, void* cookie) {
  if (event != WATCH_EVENT_ADD_FILE) {
    return ZX_OK;
  }

  netifc_cb_ctx_t* ctx = (netifc_cb_ctx_t*)cookie;
  printf("netifc: ? %s/%s\n", ctx->dirname, filename);

  int fd;
  if ((fd = openat(dirfd, filename, O_RDWR)) < 0) {
    return ZX_OK;
  }

  zx_handle_t netsvc = ZX_HANDLE_INVALID;
  zx_status_t status = fdio_get_service_handle(fd, &netsvc);
  if (status != ZX_OK) {
    goto fail_close_svc;
  }

  if (ctx->interface != NULL) {
    *(ctx->interface) = netsvc;
  }
  // If an interface was specified, check the topological path of this device and reject it if it
  // doesn't match.
  if (ctx->topological_path != NULL) {
    const char* interface = ctx->topological_path;
    char buf[1024];
    size_t actual_len;
    auto resp = fidl::WireCall<fuchsia_device::Controller>(zx::unowned_channel(netsvc))
                    .GetTopologicalPath();
    status = resp.status();
    if (status == ZX_OK) {
      if (resp->result.is_err()) {
        status = resp->result.err();
      } else {
        auto& r = resp->result.response();
        actual_len = r.path.size();
        if (actual_len > 1024) {
          goto fail_close_svc;
        }
        memcpy(buf, r.path.data(), r.path.size());
        status = ZX_OK;
      }
    }
    if (status != ZX_OK) {
      goto fail_close_svc;
    }
    buf[actual_len] = 0;

    const char* topo_path = buf;
    // Skip the instance sigil if it's present in either the topological path or the given
    // interface path.
    if (topo_path[0] == '@')
      topo_path++;
    if (interface[0] == '@')
      interface++;

    if (strncmp(topo_path, interface, sizeof(buf))) {
      goto fail_close_svc;
    }
  }

  fuchsia_hardware_ethernet_Info info;
  if (fuchsia_hardware_ethernet_DeviceGetInfo(netsvc, &info) != ZX_OK) {
    goto fail_close_svc;
  }
  if (info.features & fuchsia_hardware_ethernet_Features_WLAN) {
    // Don't run netsvc for wireless network devices
    goto fail_close_svc;
  }
  memcpy(ctx->netmac, info.mac.octets, sizeof(ctx->netmac));
  ctx->netmtu = static_cast<uint16_t>(info.mtu);

  printf("netsvc: using %s/%s\n", ctx->dirname, filename);

  // stop polling
  return ZX_ERR_STOP;

fail_close_svc:
  zx_handle_close(netsvc);
  netsvc = ZX_HANDLE_INVALID;

  return ZX_OK;
}

zx_status_t netifc_discover(const char* ethdir, const char* topological_path,
                            zx_handle_t* interface, uint8_t netmac[6]) {
  int dirfd;
  if ((dirfd = open(ethdir, O_DIRECTORY | O_RDONLY)) < 0) {
    return -1;
  }

  netifc_cb_ctx_t ctx = {
      .dirname = ethdir,
      .interface = interface,
      .topological_path = topological_path,
      .netmac = {},
      .netmtu = 0,
  };
  zx_status_t status = fdio_watch_directory(dirfd, netifc_open_cb, ZX_TIME_INFINITE, (void*)&ctx);
  close(dirfd);

  // callback returns STOP if it finds and successfully
  // opens a network interface
  if (status != ZX_ERR_STOP) {
    return -1;
  }

  memcpy(netmac, ctx.netmac, 6);
  return ZX_OK;
}
