//===--- OutputFileMap.cpp - Map of inputs to multiple outputs ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/OutputFileMap.h"
#include "swift/Basic/FileTypes.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>

using namespace swift;

llvm::Expected<OutputFileMap>
OutputFileMap::loadFromPath(StringRef Path, StringRef workingDirectory,
                            const bool addEntriesForSourceRangeDependencies) {
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
      llvm::MemoryBuffer::getFile(Path);
  if (!FileBufOrErr) {
    return llvm::errorCodeToError(FileBufOrErr.getError());
  }
  return loadFromBuffer(std::move(FileBufOrErr.get()), workingDirectory,
                        addEntriesForSourceRangeDependencies);
}

llvm::Expected<OutputFileMap>
OutputFileMap::loadFromBuffer(StringRef Data, StringRef workingDirectory,
                              bool addEntriesForSourceRangeDependencies) {
  std::unique_ptr<llvm::MemoryBuffer> Buffer{
      llvm::MemoryBuffer::getMemBuffer(Data)};
  return loadFromBuffer(std::move(Buffer), workingDirectory,
                        addEntriesForSourceRangeDependencies);
}

llvm::Expected<OutputFileMap>
OutputFileMap::loadFromBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer,
                              StringRef workingDirectory,
                              bool addEntriesForSourceRangeDependencies) {
  return parse(std::move(Buffer), workingDirectory,
               addEntriesForSourceRangeDependencies);
}

const TypeToPathMap *OutputFileMap::getOutputMapForInput(StringRef Input) const{
  auto iter = InputToOutputsMap.find(Input);
  if (iter == InputToOutputsMap.end())
    return nullptr;
  else
    return &iter->second;
}

TypeToPathMap &
OutputFileMap::getOrCreateOutputMapForInput(StringRef Input) {
  return InputToOutputsMap[Input];
}

const TypeToPathMap *OutputFileMap::getOutputMapForSingleOutput() const {
  return getOutputMapForInput(StringRef());
}

TypeToPathMap &
OutputFileMap::getOrCreateOutputMapForSingleOutput() {
  return InputToOutputsMap[StringRef()];
}

void OutputFileMap::dump(llvm::raw_ostream &os, bool Sort) const {
  using TypePathPair = std::pair<file_types::ID, std::string>;

  auto printOutputPair = [&os](StringRef InputPath,
                               const TypePathPair &OutputPair) -> void {
    os << InputPath << " -> " << file_types::getTypeName(OutputPair.first)
       << ": \"" << OutputPair.second << "\"\n";
  };

  if (Sort) {
    using PathMapPair = std::pair<StringRef, TypeToPathMap>;
    std::vector<PathMapPair> Maps;
    for (auto &InputPair : InputToOutputsMap) {
      Maps.emplace_back(InputPair.first(), InputPair.second);
    }
    std::sort(Maps.begin(), Maps.end(), [] (const PathMapPair &LHS,
                                            const PathMapPair &RHS) -> bool {
      return LHS.first < RHS.first;
    });
    for (auto &InputPair : Maps) {
      const TypeToPathMap &Map = InputPair.second;
      std::vector<TypePathPair> Pairs;
      Pairs.insert(Pairs.end(), Map.begin(), Map.end());
      std::sort(Pairs.begin(), Pairs.end());
      for (auto &OutputPair : Pairs) {
        printOutputPair(InputPair.first, OutputPair);
      }
    }
  } else {
    for (auto &InputPair : InputToOutputsMap) {
      const TypeToPathMap &Map = InputPair.second;
      for (const TypePathPair &OutputPair : Map) {
        printOutputPair(InputPair.first(), OutputPair);
      }
    }
  }
}

static void writeQuotedEscaped(llvm::raw_ostream &os,
                               const StringRef fileName) {
  os << "\"" << llvm::yaml::escape(fileName) << "\"";
}

void OutputFileMap::write(llvm::raw_ostream &os,
                          ArrayRef<StringRef> inputs) const {
  for (const auto &input : inputs) {
    writeQuotedEscaped(os, input);
    os << ":";

    const TypeToPathMap *outputMap = getOutputMapForInput(input);
    if (!outputMap) {
      // The map doesn't have an entry for this input. (Perhaps there were no
      // outputs and thus the entry was never created.) Put an empty sub-map
      // into the output and move on.
      os << " {}\n";
      continue;
    }

    os << "\n";
    // DenseMap is unordered. If you write a test, please sort the output.
    for (auto &typeAndOutputPath : *outputMap) {
      file_types::ID type = typeAndOutputPath.getFirst();
      StringRef output = typeAndOutputPath.getSecond();
      os << "  " << file_types::getTypeName(type) << ": ";
      writeQuotedEscaped(os, output);
      os << "\n";
    }
  }
}

llvm::Expected<OutputFileMap>
OutputFileMap::parse(std::unique_ptr<llvm::MemoryBuffer> Buffer,
                     StringRef workingDirectory,
                     const bool addEntriesForSourceRangeDependencies) {
  auto constructError =
      [](const char *errorString) -> llvm::Expected<OutputFileMap> {
    return llvm::make_error<llvm::StringError>(errorString,
                                               llvm::inconvertibleErrorCode());
  };
  /// FIXME: Make the returned error strings more specific by including some of
  /// the source.
  llvm::SourceMgr SM;
  llvm::yaml::Stream YAMLStream(Buffer->getMemBufferRef(), SM);
  auto I = YAMLStream.begin();
  if (I == YAMLStream.end())
    return constructError("empty YAML stream");

  auto Root = I->getRoot();
  if (!Root)
    return constructError("no root");

  OutputFileMap OFM;

  auto *Map = dyn_cast<llvm::yaml::MappingNode>(Root);
  if (!Map)
    return constructError("root was not a MappingNode");

  auto resolvePath =
      [workingDirectory](
          llvm::yaml::ScalarNode *Path,
          llvm::SmallVectorImpl<char> &PathStorage) -> StringRef {
    StringRef PathStr = Path->getValue(PathStorage);
    if (workingDirectory.empty() || PathStr.empty() || PathStr == "-" ||
        llvm::sys::path::is_absolute(PathStr)) {
      return PathStr;
    }
    // Copy the path to avoid making assumptions about how getValue deals with
    // Storage.
    SmallString<128> PathStrCopy(PathStr);
    PathStorage.clear();
    PathStorage.reserve(PathStrCopy.size() + workingDirectory.size() + 1);
    PathStorage.insert(PathStorage.begin(), workingDirectory.begin(),
                       workingDirectory.end());
    llvm::sys::path::append(PathStorage, PathStrCopy);
    return StringRef(PathStorage.data(), PathStorage.size());
  };

  for (auto &Pair : *Map) {
    llvm::yaml::Node *Key = Pair.getKey();
    llvm::yaml::Node *Value = Pair.getValue();

    if (!Key)
      return constructError("bad key");

    if (!Value)
      return constructError("bad value");

    auto *InputPath = dyn_cast<llvm::yaml::ScalarNode>(Key);
    if (!InputPath)
      return constructError("input path not a scalar node");

    llvm::yaml::MappingNode *OutputMapNode =
      dyn_cast<llvm::yaml::MappingNode>(Value);
    if (!OutputMapNode)
      return constructError("output map not a MappingNode");

    TypeToPathMap OutputMap;

    for (auto &OutputPair : *OutputMapNode) {
      llvm::yaml::Node *Key = OutputPair.getKey();
      llvm::yaml::Node *Value = OutputPair.getValue();

      auto *KindNode = dyn_cast<llvm::yaml::ScalarNode>(Key);
      if (!KindNode)
        return constructError("kind not a ScalarNode");

      auto *Path = dyn_cast<llvm::yaml::ScalarNode>(Value);
      if (!Path)
        return constructError("path not a scalar node");

      llvm::SmallString<16> KindStorage;
      file_types::ID Kind =
          file_types::lookupTypeForName(KindNode->getValue(KindStorage));

      // Ignore unknown types, so that an older swiftc can be used with a newer
      // build system.
      if (Kind == file_types::TY_INVALID)
        continue;

      llvm::SmallString<128> PathStorage;
      OutputMap.insert(std::pair<file_types::ID, std::string>(
          Kind, resolvePath(Path, PathStorage).str()));

      // HACK: fake up an SwiftRanges & CompiledSource output filenames
      if (addEntriesForSourceRangeDependencies &&
          Kind == file_types::TY_SwiftDeps) {
        // Not for the master-swiftdeps
        llvm::SmallString<128> Storage;
        if (!InputPath->getValue(Storage).empty()) {
          std::string baseName = OutputMap[Kind];
          baseName.resize(baseName.size() -
                          getExtension(file_types::TY_SwiftDeps).size());
          auto insertFilename = [&](file_types::ID type) {
            std::string s = baseName;
            s += getExtension(type);
            OutputMap.insert({type, s});
          };
          insertFilename(file_types::TY_SwiftRanges);
          insertFilename(file_types::TY_CompiledSource);
        }
      }
    }

    llvm::SmallString<128> InputStorage;
    OFM.InputToOutputsMap[resolvePath(InputPath, InputStorage)] =
        std::move(OutputMap);
  }

  if (YAMLStream.failed())
    return constructError("Output file map parse failed");

  return OFM;
}
