/*
 * Copyright (C) 2015, The Android Open Source Project
 *
 * 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 "io_delegate.h"

#include <cstring>
#include <fstream>
#include <vector>

#ifdef _WIN32
#include <direct.h>
#include <windows.h>
#undef ERROR
#else
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif

#include <android-base/strings.h>

#include "logging.h"
#include "os.h"

using std::string;
using std::unique_ptr;
using std::vector;

using android::base::Error;
using android::base::Result;
using android::base::Split;

namespace android {
namespace aidl {

bool IoDelegate::GetAbsolutePath(const string& path, string* absolute_path) {
#ifdef _WIN32

  char buf[4096];
  DWORD path_len = GetFullPathName(path.c_str(), sizeof(buf), buf, nullptr);
  if (path_len <= 0 || path_len >= sizeof(buf)) {
    AIDL_ERROR(path) << "Failed to GetFullPathName";
    return false;
  }
  *absolute_path = buf;

  return true;

#else

  if (path.empty()) {
    AIDL_ERROR(path) << "Giving up on finding an absolute path to represent the empty string.";
    return false;
  }
  if (path[0] == OS_PATH_SEPARATOR) {
    *absolute_path = path;
    return true;
  }

  char buf[4096];
  if (getcwd(buf, sizeof(buf)) == nullptr) {
    AIDL_ERROR(path) << "Path of current working directory does not fit in " << sizeof(buf)
                     << " bytes";
    return false;
  }

  *absolute_path = buf;
  *absolute_path += OS_PATH_SEPARATOR;
  *absolute_path += path;
  return true;
#endif
}

unique_ptr<string> IoDelegate::GetFileContents(
    const string& filename,
    const string& content_suffix) const {
  unique_ptr<string> contents;
  std::ifstream in(filename, std::ios::in | std::ios::binary);
  if (!in) {
    return contents;
  }
  contents.reset(new string);
  in.seekg(0, std::ios::end);
  ssize_t file_size = in.tellg();
  contents->resize(file_size + content_suffix.length());
  in.seekg(0, std::ios::beg);
  // Read the file contents into the beginning of the string
  in.read(&(*contents)[0], file_size);
  // Drop the suffix in at the end.
  contents->replace(file_size, content_suffix.length(), content_suffix);
  in.close();

  return contents;
}

unique_ptr<LineReader> IoDelegate::GetLineReader(
    const string& file_path) const {
  return LineReader::ReadFromFile(file_path);
}

bool IoDelegate::FileIsReadable(const string& path) const {
#ifdef _WIN32
  // check that the file exists and is not write-only
  return (0 == _access(path.c_str(), 0)) &&  // mode 0=exist
         (0 == _access(path.c_str(), 4));    // mode 4=readable
#else
  return (0 == access(path.c_str(), R_OK));
#endif
}

static bool CreateNestedDirs(const string& caller_base_dir, const vector<string>& nested_subdirs) {
  string base_dir = caller_base_dir;
  if (base_dir.empty()) {
    base_dir = ".";
  }
  for (const string& subdir : nested_subdirs) {
    if (base_dir[base_dir.size() - 1] != OS_PATH_SEPARATOR) {
      base_dir += OS_PATH_SEPARATOR;
    }
    base_dir += subdir;
    bool success;
#ifdef _WIN32
    success = _mkdir(base_dir.c_str()) == 0;
#else
    success = mkdir(base_dir.c_str(),
                    S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
#endif
    // On darwin when you try to mkdir("/", ...) we get EISDIR.
    if (!success && (errno != EEXIST && errno != EISDIR)) {
      AIDL_ERROR(caller_base_dir) << "Error while creating " << base_dir << ": " << strerror(errno);
      return false;
    }
  }
  return true;
}

bool IoDelegate::CreateDirForPath(const string& path) const {
  if (path.empty()) {
    return true;
  }

  string absolute_path;
  if (!GetAbsolutePath(path, &absolute_path)) {
    return false;
  }

  auto directories = Split(absolute_path, string{OS_PATH_SEPARATOR});

  // The "base" directory is just the root of the file system.  On Windows,
  // this will look like "C:\" but on Unix style file systems we get an empty
  // string after splitting "/foo" with "/"
  string base = directories[0];
  if (base.empty()) {
    base = "/";
  }
  directories.erase(directories.begin());

  // Remove the actual file in question, we're just creating the directory path.
  bool is_file = path.back() != OS_PATH_SEPARATOR;
  if (is_file) {
    directories.pop_back();
  }

  return CreateNestedDirs(base, directories);
}

unique_ptr<CodeWriter> IoDelegate::GetCodeWriter(
    const string& file_path) const {
  if (CreateDirForPath(file_path)) {
    return CodeWriter::ForFile(file_path);
  } else {
    return nullptr;
  }
}

void IoDelegate::RemovePath(const std::string& file_path) const {
#ifdef _WIN32
  _unlink(file_path.c_str());
#else
  unlink(file_path.c_str());
#endif
}

#ifdef _WIN32
Result<vector<string>> IoDelegate::ListFiles(const string&) const {
  return Error() << "File listing not implemented on Windows";
}

#else
static Result<void> add_list_files(const string& dirname, vector<string>* result) {
  AIDL_FATAL_IF(result == nullptr, dirname);
  std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(dirname.c_str()), closedir);

  if (dir == nullptr) {
    return Error() << "Failed to read directory '" << dirname << "': " << strerror(errno);
  }

  while (true) {
    errno = 0;
    struct dirent* ent = readdir(dir.get());
    if (ent == nullptr) {
      if (errno != 0) {
        return Error() << "Failed to read directory entry in '" << dirname
                       << "': " << strerror(errno);
      }
      break;
    }

    if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
      continue;
    }
    if (ent->d_type == DT_REG) {
      result->emplace_back(dirname + OS_PATH_SEPARATOR + ent->d_name);
    } else if (ent->d_type == DT_DIR) {
      if (auto ret = add_list_files(dirname + OS_PATH_SEPARATOR + ent->d_name, result); !ret.ok()) {
        return ret;
      }
    }
  }

  return Result<void>();
}

Result<vector<string>> IoDelegate::ListFiles(const string& dir) const {
  vector<string> result;
  if (auto ret = add_list_files(dir, &result); !ret.ok()) {
    return ret.error();
  }
  return result;
}
#endif

}  // namespace android
}  // namespace aidl
