// 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 "netcp.h"

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/boot/netboot.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

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

namespace {

constexpr char TMP_SUFFIX[] = ".netsvc.tmp";

struct netcp_state {
  int fd;
  off_t offset;
  // false: Filename is the open file and final destination
  // true : Filename is final destination; open file has a magic tmp suffix
  bool needs_rename;
  char filename[PATH_MAX];
};

netcp_state netcp = {
    .fd = -1,
    .offset = 0,
    .needs_rename = false,
    .filename = {0},
};

int netcp_mkdir(const char* filename) {
  const char* ptr = filename[0] == '/' ? filename + 1 : filename;
  struct stat st;
  char tmp[1024];
  for (;;) {
    ptr = strchr(ptr, '/');
    if (!ptr) {
      return 0;
    }
    memcpy(tmp, filename, ptr - filename);
    tmp[ptr - filename] = '\0';
    ptr += 1;
    if (stat(tmp, &st) < 0) {
      if (errno == ENOENT) {
        if (mkdir(tmp, 0755) < 0) {
          return -1;
        }
      } else {
        return -1;
      }
    }
  }
}

}  // namespace

int netcp_open(const char* filename, uint32_t arg, size_t* file_size) {
  if (netcp.fd >= 0) {
    printf("netsvc: closing still-open '%s', replacing with '%s'\n", netcp.filename, filename);
    close(netcp.fd);
    netcp.fd = -1;
  }
  size_t len = strlen(filename);
  strlcpy(netcp.filename, filename, sizeof(netcp.filename));

  struct stat st;
again:  // label here to catch filename=/path/to/new/directory/
  if (stat(filename, &st) == 0 && S_ISDIR(st.st_mode)) {
    errno = EISDIR;
    goto err;
  }

  switch (arg) {
    case O_RDONLY:
      netcp.needs_rename = false;
      netcp.fd = open(filename, O_RDONLY);
      if (file_size) {
        *file_size = st.st_size;
      }
      break;
    case O_WRONLY: {
      // If we're writing a file, actually write to "filename + TMP_SUFFIX",
      // and rename to the final destination when we would close. This makes
      // written files appear to atomically update.
      if (len + strlen(TMP_SUFFIX) + 1 > PATH_MAX) {
        errno = ENAMETOOLONG;
        goto err;
      }
      strcat(netcp.filename, TMP_SUFFIX);
      netcp.needs_rename = true;
      netcp.fd = open(netcp.filename, O_WRONLY | O_CREAT | O_TRUNC);
      netcp.filename[len] = '\0';
      if (netcp.fd < 0 && errno == ENOENT) {
        if (netcp_mkdir(filename) == 0) {
          goto again;
        }
      }
      break;
    }
    default:
      printf("netsvc: open '%s' with invalid mode %d\n", filename, arg);
      errno = EINVAL;
  }
  if (netcp.fd < 0) {
    goto err;
  } else {
    strlcpy(netcp.filename, filename, sizeof(netcp.filename));
    netcp.offset = 0;
  }

  return 0;
err:
  netcp.filename[0] = '\0';
  return -errno;
}

ssize_t netcp_offset_read(void* data_out, off_t offset, size_t max_len) {
  if (netcp.fd < 0) {
    printf("netsvc: read, but no open file\n");
    return -EBADF;
  }
  if (offset != netcp.offset) {
    if (lseek(netcp.fd, offset, SEEK_SET) != offset) {
      return -errno;
    }
    netcp.offset = offset;
  }
  return netcp_read(data_out, max_len);
}

ssize_t netcp_read(void* data_out, size_t data_sz) {
  if (netcp.fd < 0) {
    printf("netsvc: read, but no open file\n");
    return -EBADF;
  }
  ssize_t n = read(netcp.fd, data_out, data_sz);
  if (n < 0) {
    printf("netsvc: error reading '%s': %d\n", netcp.filename, errno);
    int result = (errno == 0) ? -EIO : -errno;
    close(netcp.fd);
    netcp.fd = -1;
    return result;
  }
  netcp.offset += n;
  return n;
}

ssize_t netcp_offset_write(const char* data, off_t offset, size_t length) {
  if (netcp.fd < 0) {
    printf("netsvc: write, but no open file\n");
    return -EBADF;
  }
  if (offset != netcp.offset) {
    if (lseek(netcp.fd, offset, SEEK_SET) != offset) {
      return -errno;
    }
    netcp.offset = offset;
  }
  return netcp_write(data, length);
}

ssize_t netcp_write(const char* data, size_t len) {
  if (netcp.fd < 0) {
    printf("netsvc: write, but no open file\n");
    return -EBADF;
  }
  ssize_t n = write(netcp.fd, data, len);
  if (n != static_cast<ssize_t>(len)) {
    printf("netsvc: error writing %s: %d\n", netcp.filename, errno);
    int result = (errno == 0) ? -EIO : -errno;
    close(netcp.fd);
    netcp.fd = -1;
    return result;
  }
  netcp.offset += len;
  return len;
}

int netcp_close() {
  int result = 0;
  if (netcp.fd < 0) {
    printf("netsvc: close, but no open file\n");
  } else {
    if (netcp.needs_rename) {
      char src[PATH_MAX];
      strlcpy(src, netcp.filename, sizeof(src));
      strlcat(src, TMP_SUFFIX, sizeof(src));
      if (rename(src, netcp.filename)) {
        printf("netsvc: failed to rename temporary file: %s\n", strerror(errno));
      }
    }
    if (close(netcp.fd)) {
      result = (errno == 0) ? -EIO : -errno;
    }
    netcp.fd = -1;
  }
  return result;
}

// Clean up if we abort before finishing a write. Close out and unlink it, rather than
// leaving an incomplete file.
void netcp_abort_write() {
  if (netcp.fd < 0) {
    return;
  }
  close(netcp.fd);
  netcp.fd = -1;
  char tmp[PATH_MAX];
  const char* filename;
  if (netcp.needs_rename) {
    strlcpy(tmp, netcp.filename, sizeof(tmp));
    strlcat(tmp, TMP_SUFFIX, sizeof(tmp));
    filename = tmp;
  } else {
    filename = netcp.filename;
  }
  if (unlink(filename) != 0) {
    printf("netsvc: failed to unlink aborted file %s\n", filename);
  }
}
