/*
 * Copyright 2015 The Kythe Authors. All rights reserved.
 *
 * 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.
 */

#ifndef KYTHE_CXX_COMMON_INDEXING_KYTHE_VFS_H_
#define KYTHE_CXX_COMMON_INDEXING_KYTHE_VFS_H_

#include "absl/types/optional.h"
#include "clang/Basic/FileManager.h"
#include "kythe/proto/analysis.pb.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"

namespace kythe {

/// \brief A filesystem that allows access only to mapped files.
///
/// IndexVFS normalizes all paths (using the working directory for
/// relative paths). This means that foo/bar/../baz is assumed to be the
/// same as foo/baz.
class IndexVFS : public llvm::vfs::FileSystem {
 public:
  /// \param working_directory The absolute path to the working directory.
  /// \param virtual_files Files to map.
  /// \param virtual_dirs Directories to map.
  /// \param style Style used to parse incoming paths. Paths are normalized
  /// to POSIX-style.
  IndexVFS(const std::string& working_directory,
           const std::vector<proto::FileData>& virtual_files,
           const std::vector<llvm::StringRef>& virtual_dirs,
           llvm::sys::path::Style style);
  /// \return nullopt if `awd` is not absolute or its style could not be
  /// detected; otherwise, the style of `awd`.
  static absl::optional<llvm::sys::path::Style>
  DetectStyleFromAbsoluteWorkingDirectory(const std::string& awd);
  ~IndexVFS();
  /// \brief Implements llvm::vfs::FileSystem::status.
  llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine& path) override;
  /// \brief Implements llvm::vfs::FileSystem::openFileForRead.
  llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> openFileForRead(
      const llvm::Twine& path) override;
  /// \brief Unimplemented and unused.
  llvm::vfs::directory_iterator dir_begin(const llvm::Twine& dir,
                                          std::error_code& error_code) override;
  /// \brief Associates a vname with a path.
  void SetVName(const std::string& path, const proto::VName& vname);
  /// \brief Returns the vname associated with some `FileEntry`.
  /// \param entry The `FileEntry` to look up.
  /// \param merge_with The `VName` to copy the vname onto.
  /// \return true if a match was found; false otherwise.
  bool get_vname(const clang::FileEntry* entry, proto::VName* merge_with);
  /// \brief Returns the vname associated with some `path`.
  /// \param path The path to look up.
  /// \param merge_with The `VName` to copy the vname onto.
  /// \return true if a match was found; false otherwise.
  bool get_vname(const llvm::StringRef& path, proto::VName* merge_with);

  /// \brief Returns a string representation of `uid` for error messages.
  std::string get_debug_uid_string(const llvm::sys::fs::UniqueID& uid);
  const std::string& working_directory() const { return working_directory_; }
  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
    return working_directory_;
  }
  std::error_code setCurrentWorkingDirectory(const llvm::Twine& Path) override {
    working_directory_ = Path.str();
    return std::error_code();
  }

 private:
  /// \brief Information kept on a file being tracked.
  struct FileRecord {
    /// Clang's VFS status record.
    llvm::vfs::Status status;
    /// Whether `vname` is valid.
    bool has_vname;
    /// This file's name, independent of path.
    std::string label;
    /// This file's VName, if set.
    proto::VName vname;
    /// This directory's children.
    std::vector<FileRecord*> children;
    /// This file's content.
    llvm::StringRef data;
  };

  /// \brief A llvm::vfs::File that wraps a `FileRecord`.
  class File : public llvm::vfs::File {
   public:
    explicit File(FileRecord* record) : record_(record) {}
    llvm::ErrorOr<llvm::vfs::Status> status() override {
      return record_->status;
    }
    std::error_code close() override { return std::error_code(); }
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(
        const llvm::Twine& Name, int64_t FileSize, bool RequiresNullTerminator,
        bool IsVolatile) override {
      name_ = Name.str();
      return llvm::MemoryBuffer::getMemBuffer(record_->data, name_,
                                              RequiresNullTerminator);
    }

   private:
    FileRecord* record_;
    std::string name_;
  };

  /// \brief Controls what happens when a missing path node is encountered.
  enum class BehaviorOnMissing {
    kCreateFile,       ///< Create intermediate directories and a final file.
    kCreateDirectory,  ///< Create intermediate and final directories.
    kReturnError       ///< Abort.
  };

  /// \brief Returns a FileRecord for the root components of `path`.
  /// \param path The path to investigate.
  /// \param create_if_missing If the root is missing, create it.
  /// \return A `FileRecord` or nullptr on abort.
  FileRecord* FileRecordForPathRoot(const llvm::Twine& path,
                                    bool create_if_missing);

  /// \param path The path to investigate.
  /// \param behavior What to do if `path` does not exist.
  /// \param size The size of the file to use if kCreateFile is relevant.
  /// \return A `FileRecord` or nullptr on abort.
  FileRecord* FileRecordForPath(llvm::StringRef path,
                                BehaviorOnMissing behavior, size_t size);

  /// \brief Creates a new or returns an existing `FileRecord`.
  /// \param parent The parent `FileRecord`.
  /// \param create_if_missing Create a FileRecord if it's missing.
  /// \param label The label to look for under `parent`.
  /// \param type The type the record should have.
  /// \param size The size that should be used if this is a file record.
  FileRecord* AllocOrReturnFileRecord(FileRecord* parent,
                                      bool create_if_missing,
                                      llvm::StringRef label,
                                      llvm::sys::fs::file_type type,
                                      size_t size);

  /// The virtual files that were included in the index.
  const std::vector<proto::FileData>& virtual_files_;
  /// The working directory. Must be absolute.
  std::string working_directory_;
  /// Maps root names to root nodes. For indexes captured from Unix
  /// environments, there will be only one root name (the empty string).
  std::map<std::string, FileRecord*> root_name_to_root_map_;
  /// Maps unique IDs to file records.
  std::map<std::pair<uint64_t, uint64_t>, FileRecord*> uid_to_record_map_;
};

}  // namespace kythe

#endif  // KYTHE_CXX_COMMON_INDEXING_KYTHE_VFS_H_
