// Copyright 2018 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/lib/util/posix_file_system.h"

#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>

#include <map>
#include <memory>
#include <sstream>

#include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "src/lib/util/file_system.h"

namespace cobalt::util {

using lib::statusor::StatusOr;

bool PosixFileSystem::MakeDirectory(const std::string &directory) {
  return mkdir(directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0;
}

class CloseDir {
 public:
  void operator()(DIR *dir) { closedir(dir); }
};

StatusOr<std::vector<std::string>> PosixFileSystem::ListFiles(const std::string &directory) {
  std::vector<std::string> files;
  std::unique_ptr<DIR, CloseDir> dir(opendir(directory.c_str()), CloseDir());
  struct dirent *ent;
  if (dir != nullptr) {
    while ((ent = readdir(dir.get())) != nullptr) {
      if (ent->d_name[0] == '.' && (ent->d_name[1] == '.' || ent->d_name[1] == '\0')) {
        continue;
      }
      files.emplace_back(ent->d_name);
    }
  } else {
    std::stringstream ss;
    ss << "Unable to open directory [" << directory << "]: " << errno;
    return Status(StatusCode::INTERNAL, ss.str());
  }

  return files;
}

bool PosixFileSystem::Delete(const std::string &file) { return std::remove(file.c_str()) == 0; }

StatusOr<size_t> PosixFileSystem::FileSize(const std::string &file) {
  struct stat st;
  if (stat(file.c_str(), &st) != 0) {
    std::stringstream ss;
    ss << "Unable to stat file [" << file << "]: " << std::strerror(errno) << "[" << errno << "]";
    return Status(StatusCode::INTERNAL, ss.str());
  }
  return static_cast<size_t>(st.st_size);
}

bool PosixFileSystem::FileExists(const std::string &file) {
  struct stat buffer;
  return (stat(file.c_str(), &buffer) == 0);
}

bool PosixFileSystem::Rename(const std::string &from, const std::string &to) {
  return std::rename(from.c_str(), to.c_str()) == 0;
}

lib::statusor::StatusOr<FileSystem::ProtoInputStreamPtr> PosixFileSystem::NewProtoInputStream(
    const std::string &file, int block_size) {
  auto fs = open(file.c_str(), O_RDWR);
  if (fs == -1) {
    std::stringstream ss;
    ss << "Unable to open file [" << file << "] in read mode.";
    return Status(ErrnoToStatusCode(errno).value_or(StatusCode::DATA_LOSS), ss.str(),
                  std::strerror(errno));
  }
  auto stream = std::make_unique<google::protobuf::io::FileInputStream>(fs, block_size);
  stream->SetCloseOnDelete(true);
  return {std::move(stream)};
}

lib::statusor::StatusOr<FileSystem::ProtoOutputStreamPtr> PosixFileSystem::NewProtoOutputStream(
    const std::string &file, bool append, int block_size) {
  auto flags = O_WRONLY | O_CREAT;
  if (append) {
    flags |= O_APPEND;
  }
  auto fs = open(file.c_str(), flags, S_IRUSR | S_IWUSR);
  if (fs == -1) {
    std::stringstream ss;
    ss << "Unable to open file [" << file << "] in write mode.";
    return Status(ErrnoToStatusCode(errno).value_or(StatusCode::DATA_LOSS), ss.str(),
                  std::strerror(errno));
  }
  auto stream = std::make_unique<google::protobuf::io::FileOutputStream>(fs, block_size);
  stream->SetCloseOnDelete(true);
  return {std::move(stream)};
}

}  // namespace cobalt::util
