/*
 * 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>
#else
#include <sys/stat.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::Split;

namespace android {
namespace aidl {

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
}

bool IoDelegate::CreatedNestedDirs(
    const string& caller_base_dir,
    const vector<string>& nested_subdirs) const {
  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)) {
      LOG(ERROR) << "Error while creating " << base_dir << ": "
                 << strerror(errno);
      return false;
    }
  }
  return true;
}

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

  string base = ".";
  if (path[0] == OS_PATH_SEPARATOR) {
    base = "/";
  }

  auto split = Split(path, string{1u, OS_PATH_SEPARATOR});
  split.pop_back();

  return CreatedNestedDirs(base, split);
}

unique_ptr<CodeWriter> IoDelegate::GetCodeWriter(
    const string& file_path) const {
  return GetFileWriter(file_path);
}

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

}  // namespace android
}  // namespace aidl
