// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/util/file_util.h"

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <streambuf>
#include <string>
#include <system_error>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "common/util/logging.h"

#ifndef _WIN32
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#endif

namespace fs = std::filesystem;

namespace verible {
namespace file {
absl::string_view Basename(absl::string_view filename) {
  auto last_slash_pos = filename.find_last_of("/\\");

  return last_slash_pos == absl::string_view::npos
             ? filename
             : filename.substr(last_slash_pos + 1);
}

absl::string_view Dirname(absl::string_view filename) {
  auto last_slash_pos = filename.find_last_of("/\\");

  return last_slash_pos == absl::string_view::npos
             ? filename
             : filename.substr(0, last_slash_pos);
}

absl::string_view Stem(absl::string_view filename) {
  auto last_dot_pos = filename.find_last_of('.');

  return last_dot_pos == absl::string_view::npos
             ? filename
             : filename.substr(0, last_dot_pos);
}

// This will always return an error, even if we can't determine anything
// from errno. Returns "fallback_msg" in that case.
static absl::Status CreateErrorStatusFromSysError(const char *fallback_msg,
                                                  int sys_error) {
  using absl::StatusCode;
  const char *const system_msg =
      sys_error == 0 ? fallback_msg : strerror(sys_error);
  switch (sys_error) {
    case EPERM:
    case EACCES:
      return absl::Status(StatusCode::kPermissionDenied, system_msg);
    case ENOENT:
      return absl::Status(StatusCode::kNotFound, system_msg);
    case EEXIST:
      return absl::Status(StatusCode::kAlreadyExists, system_msg);
    case EINVAL:
      return absl::Status(StatusCode::kInvalidArgument, system_msg);
    default:
      return absl::Status(StatusCode::kUnknown, system_msg);
  }
}

static absl::Status CreateErrorStatusFromErrno(const char *fallback_msg) {
  return CreateErrorStatusFromSysError(fallback_msg, errno);
}
static absl::Status CreateErrorStatusFromErr(const char *fallback_msg,
                                             const std::error_code &err) {
  // TODO: this assumes that err.value() returns errno-like values. Might not
  // always be the case.
  return CreateErrorStatusFromSysError(fallback_msg, err.value());
}

absl::Status UpwardFileSearch(absl::string_view start,
                              absl::string_view filename, std::string *result) {
  std::error_code err;
  const std::string search_file(filename);
  fs::path absolute_path = fs::absolute(std::string(start), err);
  if (err.value() != 0)
    return CreateErrorStatusFromErr("invalid config path specified.", err);

  fs::path probe_dir = absolute_path;
  for (;;) {
    *result = (probe_dir / search_file).string();
    if (FileExists(*result).ok()) return absl::OkStatus();
    fs::path one_up = probe_dir.parent_path();
    if (one_up == probe_dir) break;
    probe_dir = one_up;
  }
  return absl::NotFoundError("No matching file found.");
}

absl::Status FileExists(const std::string &filename) {
  std::error_code err;
  fs::file_status stat = fs::status(filename, err);

  if (err.value() != 0) {
    return absl::NotFoundError(absl::StrCat(filename, ": ", err.message()));
  }

  if (fs::is_regular_file(stat) || fs::is_fifo(stat)) {
    return absl::OkStatus();
  }

  if (fs::is_directory(stat)) {
    return absl::InvalidArgumentError(
        absl::StrCat(filename, ": is a directory, not a file"));
  }
  return absl::InvalidArgumentError(
      absl::StrCat(filename, ": not a regular file."));
}

absl::Status GetContents(absl::string_view filename, std::string *content) {
  std::ifstream fs;
  std::istream *stream = nullptr;
  const bool use_stdin = filename == "-";  // convention: honor "-" as stdin
  if (use_stdin) {
    stream = &std::cin;
  } else {
    const std::string filename_str = std::string(filename);
    absl::Status usable_file = FileExists(filename_str);
    if (!usable_file.ok()) return usable_file;  // Bail
    fs.open(filename_str.c_str());
    std::error_code err;
    const size_t prealloc = fs::file_size(filename_str, err);
    if (err.value() == 0) content->reserve(prealloc);
    stream = &fs;
  }
  if (!stream->good()) return CreateErrorStatusFromErrno("can't read");
  char buffer[4096];
  while (stream->good() && !stream->eof()) {
    stream->read(buffer, sizeof(buffer));
    content->append(buffer, stream->gcount());
  }

  // Allow stdin to be reopened for more input.
  if (use_stdin && std::cin.eof()) std::cin.clear();
  return absl::OkStatus();
}

static absl::StatusOr<std::unique_ptr<MemBlock>> AttemptMemMapFile(
    absl::string_view filename) {
#ifndef _WIN32
  class MemMapBlock final : public MemBlock {
   public:
    MemMapBlock(char *buffer, size_t size) : buffer_(buffer), size_(size) {}
    ~MemMapBlock() final { munmap(buffer_, size_); }
    absl::string_view AsStringView() const final { return {buffer_, size_}; }

   private:
    char *const buffer_;
    const size_t size_;
  };

  const std::string nul_terminated_filename(filename);
  const int fd = open(nul_terminated_filename.c_str(), O_RDONLY);
  if (fd < 0) {
    return CreateErrorStatusFromErrno("Can't open file");
  }

  struct stat s;
  if (fstat(fd, &s) < 0) {
    close(fd);
    return CreateErrorStatusFromErrno("can't stat");
  }

  const size_t file_size = s.st_size;
  void *const buffer = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);
  close(fd);
  if (buffer == MAP_FAILED) {
    return CreateErrorStatusFromErrno("Can't mmap file");
  }

  return std::make_unique<MemMapBlock>((char *)buffer, file_size);
#else
  // TODO: implement some memory mapping on Windows.
  return absl::UnimplementedError("No windows mmap implementation yet.");
#endif
}

absl::StatusOr<std::unique_ptr<MemBlock>> GetContentAsMemBlock(
    absl::string_view filename) {
  auto mmap_result = AttemptMemMapFile(filename);
  if (mmap_result.status().ok()) {
    return mmap_result;
  }

  // Still here ? Well, let's try the traditional way
  auto mem_block = std::make_unique<StringMemBlock>();
  if (auto status = GetContents(filename, mem_block->mutable_content());
      !status.ok()) {
    return status;
  }
  return mem_block;
}

absl::Status SetContents(absl::string_view filename,
                         absl::string_view content) {
  VLOG(1) << __FUNCTION__ << ": Writing file: " << filename;
  std::ofstream f(std::string(filename).c_str());
  if (!f.good()) return CreateErrorStatusFromErrno("can't write.");
  f << content;
  return absl::OkStatus();
}

std::string JoinPath(absl::string_view base, absl::string_view name) {
  // Make sure the second element is not already absolute, otherwise
  // the fs::path() uses this as toplevel path. This is only an issue with
  // Unix paths. Windows paths will have a c:\ for explicit full-pathness
  while (!name.empty() && name[0] == '/') {
    name = name.substr(1);
  }

  fs::path p = fs::path(std::string(base)) / fs::path(std::string(name));
  return p.lexically_normal().string();
}

absl::Status CreateDir(absl::string_view dir) {
  const std::string path(dir);
  std::error_code err;
  if (fs::create_directory(path, err) || err.value() == 0)
    return absl::OkStatus();

  return CreateErrorStatusFromErr("can't create directory", err);
}

absl::StatusOr<Directory> ListDir(absl::string_view dir) {
  std::error_code err;
  Directory d;

  d.path = dir.empty() ? "." : std::string(dir);

  fs::file_status stat = fs::status(d.path, err);
  if (err.value() != 0)
    return CreateErrorStatusFromErr("Opening directory", err);
  if (!fs::is_directory(stat)) {
    return absl::InvalidArgumentError(absl::StrCat(dir, ": not a directory"));
  }

  for (const fs::directory_entry &entry : fs::directory_iterator(d.path)) {
    const std::string entry_name = entry.path().string();
    if (entry.is_directory()) {
      d.directories.push_back(entry_name);
    } else {
      d.files.push_back(entry_name);
    }
  }

  std::sort(d.files.begin(), d.files.end());
  std::sort(d.directories.begin(), d.directories.end());
  return d;
}

namespace testing {

std::string RandomFileBasename(absl::string_view prefix) {
  return absl::StrCat(prefix, "-", rand());
}

ScopedTestFile::ScopedTestFile(absl::string_view base_dir,
                               absl::string_view content,
                               absl::string_view use_this_filename)
    // There is no secrecy needed for test files,
    // file name just need to be unique enough.
    : filename_(JoinPath(base_dir, use_this_filename.empty()
                                       ? RandomFileBasename("scoped-file")
                                       : use_this_filename)) {
  const absl::Status status = SetContents(filename_, content);
  CHECK(status.ok()) << status.message();  // ok for test-only code
}

ScopedTestFile::~ScopedTestFile() { unlink(filename_.c_str()); }
}  // namespace testing
}  // namespace file
}  // namespace verible
