// Copyright 2020 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 "src/developer/shell/mirror/wire_format.h"

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cstddef>
#include <fstream>
#include <iterator>
#include <memory>

#include "src/developer/shell/mirror/common.h"
#include "src/lib/fxl/logging.h"

namespace shell::mirror {

int Files::AddFile(const std::filesystem::path &path, std::unique_ptr<char[]> &&contents,
                   int length) {
  for (const auto &file : files_) {
    if (file.Name() == path) {
      // already present.  Consider replacing?
      return 0;
    }
  }

  files_.emplace_back(path, std::move(contents), length);
  return 0;
}

int Files::AddFile(const std::filesystem::path &path) {
  FILE *f = fopen(path.c_str(), "rb");
  if (f == nullptr) {
    return -1;
  }
  int err = fseek(f, 0, SEEK_END);
  if (err == -1) {
    return err;
  }
  long file_size = ftell(f);
  err = fseek(f, 0, SEEK_SET);
  if (err == -1) {
    return err;
  }

  std::unique_ptr<char[]> contents = std::make_unique<char[]>(file_size + 1);
  fread(contents.get(), file_size, 1, f);
  fclose(f);

  contents[file_size] = 0;

  return AddFile(path, std::move(contents), file_size);
}

namespace {

template <class T>
void WriteFixedLength(std::vector<char> *sink, T size) {
  for (std::size_t i = 0; i < sizeof(T); i++) {
    char *size_ch = reinterpret_cast<char *>(&size) + i;
    sink->push_back(*size_ch);
  }
}

}  // namespace

// Dumps the files to a vector, and returns that vector.
// Note that this requires enough memory to hold all of the files.
int Files::DumpFiles(std::vector<char> *sink) {
  WriteFixedLength<uint64_t>(sink, files_.size());
  std::string root = root_dir_.string();

  for (const auto &file : files_) {
    // Calculate remote pathname (i.e., remove local root path prefix)
    std::string name = file.Name();
    if (name.find(root_dir_.string()) == 0) {
      name.erase(0, root.length());
      while (name[0] == std::filesystem::path::preferred_separator) {
        name.erase(0, 1);
      }
    }
    // Write path length
    uint64_t path_size = name.length();
    WriteFixedLength<uint64_t>(sink, path_size);
    sink->reserve(sink->size() + path_size);

    // Write path
    std::vector<char> name_vec(name.begin(), name.end());
    sink->insert(sink->end(), name.begin(), name.end());

    std::string_view data_view = file.View();
    int data_size = data_view.size();
    const char *data = data_view.data();
    WriteFixedLength<uint64_t>(sink, data_size);
    sink->reserve(sink->size() + data_size);
    sink->insert(sink->end(), data, data + data_size);
  }
  return 0;
}

namespace {

// Read like read(2), potentially selecting on the fd first, potentially with a timeout, and
// continuing to read until the requested number of bytes has been read.
Err DoRead(int fd, void *buf, size_t count, struct timeval *timeout) {
  struct stat statbuf;
  int statres = fstat(fd, &statbuf);
  // Fuchsia doesn't support select on regular files.
  if (statres == -1 || !S_ISREG(statbuf.st_mode)) {
    fd_set set;
    struct timeval tv;
    FD_ZERO(&set);
    FD_SET(fd, &set);
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    if (timeout == nullptr) {
      timeout = &tv;
    }
    int retval = select(fd + 1, &set, nullptr, nullptr, timeout);
    if (retval == -1) {
      std::string error = "Error in select(): " + std::string(strerror(errno));
      return Err(kRead, error);
    }
    if (retval != 1) {
      std::string error = "Timed out waiting for reload server: " + std::to_string(retval);
      return Err(kRead, error);
    }
  }

  int ct;
  int to_be_counted = count;
  while (to_be_counted != 0) {
    if ((ct = read(fd, buf, to_be_counted)) == -1) {
      std::string error = "Error reading: " + std::string(strerror(errno));
      return Err(kRead, error);
    }
    to_be_counted -= ct;
  }
  return Err();
}

}  // namespace

#define READ_RET(fd, buf, count)                                          \
  do {                                                                    \
    void *vbuf = const_cast<void *>(reinterpret_cast<const void *>(buf)); \
    Err res = DoRead(fd, vbuf, count, timeout);                           \
    if (res.code != 0) {                                                  \
      *error = res;                                                       \
      return Files();                                                     \
    }                                                                     \
  } while (0)

Files Files::FilesFromFD(int fd, Err *error, struct timeval *timeout) {
  Files files;
  uint64_t num_files;
  READ_RET(fd, &num_files, sizeof(num_files));
  files.files_.reserve(num_files);
  for (size_t i = 0; i < num_files; i++) {
    uint64_t path_size;
    READ_RET(fd, &path_size, sizeof(path_size));
    std::unique_ptr<char[]> path_name(new char[path_size + 1]);
    READ_RET(fd, path_name.get(), path_size);
    path_name.get()[path_size] = '\0';

    uint64_t file_size;
    READ_RET(fd, &file_size, sizeof(file_size));
    std::unique_ptr<char[]> data(new char[file_size]);
    READ_RET(fd, data.get(), file_size);

    files.files_.emplace_back(path_name.get(), std::move(data), file_size);
  }

  return files;
}

}  // namespace shell::mirror
