//===- TextStubV5.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implements Text Stub JSON mappings.
//
//===----------------------------------------------------------------------===//
#include "TextStubCommon.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/JSON.h"
#include <utility>

// clang-format off
/*

JSON Format specification.

All library level keys, accept target values and are defaulted if not specified. 

{
"tapi_tbd_version": 5,                            # Required: TBD version for all documents in file
"main_library": {                                 # Required: top level library
  "target_info": [                                # Required: target information 
    {
      "target": "x86_64-macos",
      "min_deployment": "10.14"                   # Required: minimum OS deployment version
    },
    {
      "target": "arm64-macos",
      "min_deployment": "10.14"
    },
    {
      "target": "arm64-maccatalyst",
      "min_deployment": "12.1"
    }],
  "flags":[{"attributes": ["flat_namespace"]}],     # Optional:
  "install_names":[{"name":"/S/L/F/Foo.fwk/Foo"}],  # Required: library install name 
  "current_versions":[{"version": "1.2"}],          # Optional: defaults to 1
  "compatibility_versions":[{ "version": "1.1"}],   # Optional: defaults to 1
  "rpaths": [                                       # Optional: 
    {
      "targets": ["x86_64-macos"],                  # Optional: defaults to targets in `target-info`
      "paths": ["@executable_path/.../Frameworks"]
    }],
  "parent_umbrellas": [{"umbrella": "System"}],
  "allowable_clients": [{"clients": ["ClientA"]}],
  "reexported_libraries": [{"names": ["/u/l/l/foo.dylib"]}],
  "exported_symbols": [{                            # List of export symbols section
      "targets": ["x86_64-macos", "arm64-macos"],   # Optional: defaults to targets in `target-info`
        "text": {                                   # List of Text segment symbols 
          "global": [ "_func" ],
          "weak": [],
          "thread_local": []
        },
        "data": { ... },                            # List of Data segment symbols
   }],
  "reexported_symbols": [{  ... }],                 # List of reexported symbols section
  "undefined_symbols": [{ ... }]                    # List of undefined symbols section
},
"libraries": [                                      # Optional: Array of inlined libraries
  {...}, {...}, {...}
]
}
*/
// clang-format on

using namespace llvm;
using namespace llvm::json;
using namespace llvm::MachO;

namespace {
struct JSONSymbol {
  SymbolKind Kind;
  std::string Name;
  SymbolFlags Flags;
};

using AttrToTargets = std::map<std::string, TargetList>;
using TargetsToSymbols =
    SmallVector<std::pair<TargetList, std::vector<JSONSymbol>>>;

enum TBDKey : size_t {
  TBDVersion = 0U,
  MainLibrary,
  Documents,
  TargetInfo,
  Targets,
  Target,
  Deployment,
  Flags,
  Attributes,
  InstallName,
  CurrentVersion,
  CompatibilityVersion,
  Version,
  SwiftABI,
  ABI,
  ParentUmbrella,
  Umbrella,
  AllowableClients,
  Clients,
  ReexportLibs,
  Names,
  Name,
  Exports,
  Reexports,
  Undefineds,
  Data,
  Text,
  Weak,
  ThreadLocal,
  Globals,
  ObjCClass,
  ObjCEHType,
  ObjCIvar,
  RPath,
  Paths,
};

std::array<StringRef, 64> Keys = {
    "tapi_tbd_version",
    "main_library",
    "libraries",
    "target_info",
    "targets",
    "target",
    "min_deployment",
    "flags",
    "attributes",
    "install_names",
    "current_versions",
    "compatibility_versions",
    "version",
    "swift_abi",
    "abi",
    "parent_umbrellas",
    "umbrella",
    "allowable_clients",
    "clients",
    "reexported_libraries",
    "names",
    "name",
    "exported_symbols",
    "reexported_symbols",
    "undefined_symbols",
    "data",
    "text",
    "weak",
    "thread_local",
    "global",
    "objc_class",
    "objc_eh_type",
    "objc_ivar",
    "rpaths",
    "paths",
};

static llvm::SmallString<128> getParseErrorMsg(TBDKey Key) {
  return {"invalid ", Keys[Key], " section"};
}

static llvm::SmallString<128> getSerializeErrorMsg(TBDKey Key) {
  return {"missing ", Keys[Key], " information"};
}

class JSONStubError : public llvm::ErrorInfo<llvm::json::ParseError> {
public:
  JSONStubError(Twine ErrMsg) : Message(ErrMsg.str()) {}

  void log(llvm::raw_ostream &OS) const override { OS << Message << "\n"; }
  std::error_code convertToErrorCode() const override {
    return llvm::inconvertibleErrorCode();
  }

private:
  std::string Message;
};

template <typename JsonT, typename StubT = JsonT>
Expected<StubT> getRequiredValue(
    TBDKey Key, const Object *Obj,
    std::function<std::optional<JsonT>(const Object *, StringRef)> GetValue,
    std::function<std::optional<StubT>(JsonT)> Validate = nullptr) {
  std::optional<JsonT> Val = GetValue(Obj, Keys[Key]);
  if (!Val)
    return make_error<JSONStubError>(getParseErrorMsg(Key));

  if (Validate == nullptr)
    return static_cast<StubT>(*Val);

  std::optional<StubT> Result = Validate(*Val);
  if (!Result.has_value())
    return make_error<JSONStubError>(getParseErrorMsg(Key));
  return Result.value();
}

template <typename JsonT, typename StubT = JsonT>
Expected<StubT> getRequiredValue(
    TBDKey Key, const Object *Obj,
    std::function<std::optional<JsonT>(const Object *, StringRef)> GetValue,
    StubT DefaultValue, std::function<std::optional<StubT>(JsonT)> Validate) {
  std::optional<JsonT> Val = GetValue(Obj, Keys[Key]);
  if (!Val)
    return DefaultValue;

  std::optional<StubT> Result;
  Result = Validate(*Val);
  if (!Result.has_value())
    return make_error<JSONStubError>(getParseErrorMsg(Key));
  return Result.value();
}

Error collectFromArray(TBDKey Key, const Object *Obj,
                       std::function<void(StringRef)> Append,
                       bool IsRequired = false) {
  const auto *Values = Obj->getArray(Keys[Key]);
  if (!Values) {
    if (IsRequired)
      return make_error<JSONStubError>(getParseErrorMsg(Key));
    return Error::success();
  }

  for (const Value &Val : *Values) {
    auto ValStr = Val.getAsString();
    if (!ValStr.has_value())
      return make_error<JSONStubError>(getParseErrorMsg(Key));
    Append(ValStr.value());
  }

  return Error::success();
}

namespace StubParser {

Expected<FileType> getVersion(const Object *File) {
  auto VersionOrErr = getRequiredValue<int64_t, FileType>(
      TBDKey::TBDVersion, File, &Object::getInteger,
      [](int64_t Val) -> std::optional<FileType> {
        unsigned Result = Val;
        if (Result != 5)
          return std::nullopt;
        return FileType::TBD_V5;
      });

  if (!VersionOrErr)
    return VersionOrErr.takeError();
  return *VersionOrErr;
}

Expected<TargetList> getTargets(const Object *Section) {
  const auto *Targets = Section->getArray(Keys[TBDKey::Targets]);
  if (!Targets)
    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Targets));

  TargetList IFTargets;
  for (const Value &JSONTarget : *Targets) {
    auto TargetStr = JSONTarget.getAsString();
    if (!TargetStr.has_value())
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
    auto TargetOrErr = Target::create(TargetStr.value());
    if (!TargetOrErr)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
    IFTargets.push_back(*TargetOrErr);
  }
  return std::move(IFTargets);
}

Expected<TargetList> getTargetsSection(const Object *Section) {
  const Array *Targets = Section->getArray(Keys[TBDKey::TargetInfo]);
  if (!Targets)
    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Targets));

  TargetList IFTargets;
  for (const Value &JSONTarget : *Targets) {
    const auto *Obj = JSONTarget.getAsObject();
    if (!Obj)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
    auto TargetStr =
        getRequiredValue<StringRef>(TBDKey::Target, Obj, &Object::getString);
    if (!TargetStr)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
    auto VersionStr = getRequiredValue<StringRef>(TBDKey::Deployment, Obj,
                                                  &Object::getString);
    if (!VersionStr)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Deployment));
    VersionTuple Version;
    if (Version.tryParse(*VersionStr))
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Deployment));
    auto TargetOrErr = Target::create(*TargetStr);
    if (!TargetOrErr)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Target));
    TargetOrErr->MinDeployment = Version;
    // Convert to LLVM::Triple to accurately compute minOS + platform + arch
    // pairing.
    IFTargets.push_back(
        MachO::Target(Triple(getTargetTripleName(*TargetOrErr))));
  }
  return std::move(IFTargets);
}

Error collectSymbolsFromSegment(const Object *Segment, TargetsToSymbols &Result,
                                SymbolFlags SectionFlag) {
  auto Err = collectFromArray(
      TBDKey::Globals, Segment, [&Result, &SectionFlag](StringRef Name) {
        JSONSymbol Sym = {SymbolKind::GlobalSymbol, Name.str(), SectionFlag};
        Result.back().second.emplace_back(Sym);
      });
  if (Err)
    return Err;

  Err = collectFromArray(
      TBDKey::ObjCClass, Segment, [&Result, &SectionFlag](StringRef Name) {
        JSONSymbol Sym = {SymbolKind::ObjectiveCClass, Name.str(), SectionFlag};
        Result.back().second.emplace_back(Sym);
      });
  if (Err)
    return Err;

  Err = collectFromArray(TBDKey::ObjCEHType, Segment,
                         [&Result, &SectionFlag](StringRef Name) {
                           JSONSymbol Sym = {SymbolKind::ObjectiveCClassEHType,
                                             Name.str(), SectionFlag};
                           Result.back().second.emplace_back(Sym);
                         });
  if (Err)
    return Err;

  Err = collectFromArray(
      TBDKey::ObjCIvar, Segment, [&Result, &SectionFlag](StringRef Name) {
        JSONSymbol Sym = {SymbolKind::ObjectiveCInstanceVariable, Name.str(),
                          SectionFlag};
        Result.back().second.emplace_back(Sym);
      });
  if (Err)
    return Err;

  SymbolFlags WeakFlag =
      SectionFlag |
      (((SectionFlag & SymbolFlags::Undefined) == SymbolFlags::Undefined)
           ? SymbolFlags::WeakReferenced
           : SymbolFlags::WeakDefined);
  Err = collectFromArray(
      TBDKey::Weak, Segment, [&Result, WeakFlag](StringRef Name) {
        JSONSymbol Sym = {SymbolKind::GlobalSymbol, Name.str(), WeakFlag};
        Result.back().second.emplace_back(Sym);
      });
  if (Err)
    return Err;

  Err = collectFromArray(
      TBDKey::ThreadLocal, Segment, [&Result, SectionFlag](StringRef Name) {
        JSONSymbol Sym = {SymbolKind::GlobalSymbol, Name.str(),
                          SymbolFlags::ThreadLocalValue | SectionFlag};
        Result.back().second.emplace_back(Sym);
      });
  if (Err)
    return Err;

  return Error::success();
}

Expected<StringRef> getNameSection(const Object *File) {
  const Array *Section = File->getArray(Keys[TBDKey::InstallName]);
  if (!Section)
    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::InstallName));

  assert(!Section->empty() && "unexpected missing install name");
  // TODO: Just take first for now.
  const auto *Obj = Section->front().getAsObject();
  if (!Obj)
    return make_error<JSONStubError>(getParseErrorMsg(TBDKey::InstallName));

  return getRequiredValue<StringRef>(TBDKey::Name, Obj, &Object::getString);
}

Expected<TargetsToSymbols> getSymbolSection(const Object *File, TBDKey Key,
                                            TargetList &Targets) {

  const Array *Section = File->getArray(Keys[Key]);
  if (!Section)
    return TargetsToSymbols();

  SymbolFlags SectionFlag;
  switch (Key) {
  case TBDKey::Reexports:
    SectionFlag = SymbolFlags::Rexported;
    break;
  case TBDKey::Undefineds:
    SectionFlag = SymbolFlags::Undefined;
    break;
  default:
    SectionFlag = SymbolFlags::None;
    break;
  };

  TargetsToSymbols Result;
  TargetList MappedTargets;
  for (auto Val : *Section) {
    auto *Obj = Val.getAsObject();
    if (!Obj)
      continue;

    auto TargetsOrErr = getTargets(Obj);
    if (!TargetsOrErr) {
      MappedTargets = Targets;
      consumeError(TargetsOrErr.takeError());
    } else {
      MappedTargets = *TargetsOrErr;
    }
    Result.emplace_back(
        std::make_pair(std::move(MappedTargets), std::vector<JSONSymbol>()));

    auto *DataSection = Obj->getObject(Keys[TBDKey::Data]);
    auto *TextSection = Obj->getObject(Keys[TBDKey::Text]);
    // There should be at least one valid section.
    if (!DataSection && !TextSection)
      return make_error<JSONStubError>(getParseErrorMsg(Key));

    if (DataSection) {
      auto Err = collectSymbolsFromSegment(DataSection, Result,
                                           SectionFlag | SymbolFlags::Data);
      if (Err)
        return std::move(Err);
    }
    if (TextSection) {
      auto Err = collectSymbolsFromSegment(TextSection, Result,
                                           SectionFlag | SymbolFlags::Text);
      if (Err)
        return std::move(Err);
    }
  }

  return std::move(Result);
}

Expected<AttrToTargets> getLibSection(const Object *File, TBDKey Key,
                                      TBDKey SubKey,
                                      const TargetList &Targets) {
  auto *Section = File->getArray(Keys[Key]);
  if (!Section)
    return AttrToTargets();

  AttrToTargets Result;
  TargetList MappedTargets;
  for (auto Val : *Section) {
    auto *Obj = Val.getAsObject();
    if (!Obj)
      continue;

    auto TargetsOrErr = getTargets(Obj);
    if (!TargetsOrErr) {
      MappedTargets = Targets;
      consumeError(TargetsOrErr.takeError());
    } else {
      MappedTargets = *TargetsOrErr;
    }
    auto Err =
        collectFromArray(SubKey, Obj, [&Result, &MappedTargets](StringRef Key) {
          Result[Key.str()] = MappedTargets;
        });
    if (Err)
      return std::move(Err);
  }

  return std::move(Result);
}

Expected<AttrToTargets> getUmbrellaSection(const Object *File,
                                           const TargetList &Targets) {
  const auto *Umbrella = File->getArray(Keys[TBDKey::ParentUmbrella]);
  if (!Umbrella)
    return AttrToTargets();

  AttrToTargets Result;
  TargetList MappedTargets;
  for (auto Val : *Umbrella) {
    auto *Obj = Val.getAsObject();
    if (!Obj)
      return make_error<JSONStubError>(
          getParseErrorMsg(TBDKey::ParentUmbrella));

    // Get Targets section.
    auto TargetsOrErr = getTargets(Obj);
    if (!TargetsOrErr) {
      MappedTargets = Targets;
      consumeError(TargetsOrErr.takeError());
    } else {
      MappedTargets = *TargetsOrErr;
    }

    auto UmbrellaOrErr =
        getRequiredValue<StringRef>(TBDKey::Umbrella, Obj, &Object::getString);
    if (!UmbrellaOrErr)
      return UmbrellaOrErr.takeError();
    Result[UmbrellaOrErr->str()] = Targets;
  }
  return std::move(Result);
}

Expected<uint8_t> getSwiftVersion(const Object *File) {
  const Array *Versions = File->getArray(Keys[TBDKey::SwiftABI]);
  if (!Versions)
    return 0;

  for (const auto &Val : *Versions) {
    const auto *Obj = Val.getAsObject();
    if (!Obj)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::SwiftABI));

    // TODO: Take first for now.
    return getRequiredValue<int64_t, uint8_t>(TBDKey::ABI, Obj,
                                              &Object::getInteger);
  }

  return 0;
}

Expected<PackedVersion> getPackedVersion(const Object *File, TBDKey Key) {
  const Array *Versions = File->getArray(Keys[Key]);
  if (!Versions)
    return PackedVersion(1, 0, 0);

  for (const auto &Val : *Versions) {
    const auto *Obj = Val.getAsObject();
    if (!Obj)
      return make_error<JSONStubError>(getParseErrorMsg(Key));

    auto ValidatePV = [](StringRef Version) -> std::optional<PackedVersion> {
      PackedVersion PV;
      auto [success, truncated] = PV.parse64(Version);
      if (!success || truncated)
        return std::nullopt;
      return PV;
    };
    // TODO: Take first for now.
    return getRequiredValue<StringRef, PackedVersion>(
        TBDKey::Version, Obj, &Object::getString, PackedVersion(1, 0, 0),
        ValidatePV);
  }

  return PackedVersion(1, 0, 0);
}

Expected<TBDFlags> getFlags(const Object *File) {
  TBDFlags Flags = TBDFlags::None;
  const Array *Section = File->getArray(Keys[TBDKey::Flags]);
  if (!Section)
    return Flags;

  for (auto &Val : *Section) {
    // TODO: Just take first for now.
    const auto *Obj = Val.getAsObject();
    if (!Obj)
      return make_error<JSONStubError>(getParseErrorMsg(TBDKey::Flags));

    auto FlagsOrErr =
        collectFromArray(TBDKey::Attributes, Obj, [&Flags](StringRef Flag) {
          TBDFlags TBDFlag =
              StringSwitch<TBDFlags>(Flag)
                  .Case("flat_namespace", TBDFlags::FlatNamespace)
                  .Case("not_app_extension_safe",
                        TBDFlags::NotApplicationExtensionSafe)
                  .Default(TBDFlags::None);
          Flags |= TBDFlag;
        });

    if (FlagsOrErr)
      return std::move(FlagsOrErr);

    return Flags;
  }

  return Flags;
}

using IFPtr = std::unique_ptr<InterfaceFile>;
Expected<IFPtr> parseToInterfaceFile(const Object *File) {
  auto TargetsOrErr = getTargetsSection(File);
  if (!TargetsOrErr)
    return TargetsOrErr.takeError();
  TargetList Targets = *TargetsOrErr;

  auto NameOrErr = getNameSection(File);
  if (!NameOrErr)
    return NameOrErr.takeError();
  StringRef Name = *NameOrErr;

  auto CurrVersionOrErr = getPackedVersion(File, TBDKey::CurrentVersion);
  if (!CurrVersionOrErr)
    return CurrVersionOrErr.takeError();
  PackedVersion CurrVersion = *CurrVersionOrErr;

  auto CompVersionOrErr = getPackedVersion(File, TBDKey::CompatibilityVersion);
  if (!CompVersionOrErr)
    return CompVersionOrErr.takeError();
  PackedVersion CompVersion = *CompVersionOrErr;

  auto SwiftABIOrErr = getSwiftVersion(File);
  if (!SwiftABIOrErr)
    return SwiftABIOrErr.takeError();
  uint8_t SwiftABI = *SwiftABIOrErr;

  auto FlagsOrErr = getFlags(File);
  if (!FlagsOrErr)
    return FlagsOrErr.takeError();
  TBDFlags Flags = *FlagsOrErr;

  auto UmbrellasOrErr = getUmbrellaSection(File, Targets);
  if (!UmbrellasOrErr)
    return UmbrellasOrErr.takeError();
  AttrToTargets Umbrellas = *UmbrellasOrErr;

  auto ClientsOrErr =
      getLibSection(File, TBDKey::AllowableClients, TBDKey::Clients, Targets);
  if (!ClientsOrErr)
    return ClientsOrErr.takeError();
  AttrToTargets Clients = *ClientsOrErr;

  auto RLOrErr =
      getLibSection(File, TBDKey::ReexportLibs, TBDKey::Names, Targets);
  if (!RLOrErr)
    return RLOrErr.takeError();
  AttrToTargets ReexportLibs = std::move(*RLOrErr);

  auto RPathsOrErr = getLibSection(File, TBDKey::RPath, TBDKey::Paths, Targets);
  if (!RPathsOrErr)
    return RPathsOrErr.takeError();
  AttrToTargets RPaths = std::move(*RPathsOrErr);

  auto ExportsOrErr = getSymbolSection(File, TBDKey::Exports, Targets);
  if (!ExportsOrErr)
    return ExportsOrErr.takeError();
  TargetsToSymbols Exports = std::move(*ExportsOrErr);

  auto ReexportsOrErr = getSymbolSection(File, TBDKey::Reexports, Targets);
  if (!ReexportsOrErr)
    return ReexportsOrErr.takeError();
  TargetsToSymbols Reexports = std::move(*ReexportsOrErr);

  auto UndefinedsOrErr = getSymbolSection(File, TBDKey::Undefineds, Targets);
  if (!UndefinedsOrErr)
    return UndefinedsOrErr.takeError();
  TargetsToSymbols Undefineds = std::move(*UndefinedsOrErr);

  IFPtr F(new InterfaceFile);
  F->setInstallName(Name);
  F->setCurrentVersion(CurrVersion);
  F->setCompatibilityVersion(CompVersion);
  F->setSwiftABIVersion(SwiftABI);
  F->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
  F->setApplicationExtensionSafe(
      !(Flags & TBDFlags::NotApplicationExtensionSafe));
  for (auto &T : Targets)
    F->addTarget(T);
  for (auto &[Lib, Targets] : Clients)
    for (auto Target : Targets)
      F->addAllowableClient(Lib, Target);
  for (auto &[Lib, Targets] : ReexportLibs)
    for (auto Target : Targets)
      F->addReexportedLibrary(Lib, Target);
  for (auto &[Lib, Targets] : Umbrellas)
    for (auto Target : Targets)
      F->addParentUmbrella(Target, Lib);
  for (auto &[Path, Targets] : RPaths)
    for (auto Target : Targets)
      F->addRPath(Target, Path);
  for (auto &[Targets, Symbols] : Exports)
    for (auto &Sym : Symbols)
      F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);
  for (auto &[Targets, Symbols] : Reexports)
    for (auto &Sym : Symbols)
      F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);
  for (auto &[Targets, Symbols] : Undefineds)
    for (auto &Sym : Symbols)
      F->addSymbol(Sym.Kind, Sym.Name, Targets, Sym.Flags);

  return std::move(F);
}

Expected<std::vector<IFPtr>> getInlinedLibs(const Object *File) {
  std::vector<IFPtr> IFs;
  const Array *Files = File->getArray(Keys[TBDKey::Documents]);
  if (!Files)
    return std::move(IFs);

  for (auto Lib : *Files) {
    auto IFOrErr = parseToInterfaceFile(Lib.getAsObject());
    if (!IFOrErr)
      return IFOrErr.takeError();
    auto IF = std::move(*IFOrErr);
    IFs.emplace_back(std::move(IF));
  }
  return std::move(IFs);
}

} // namespace StubParser
} // namespace

Expected<std::unique_ptr<InterfaceFile>>
MachO::getInterfaceFileFromJSON(StringRef JSON) {
  auto ValOrErr = parse(JSON);
  if (!ValOrErr)
    return ValOrErr.takeError();

  auto *Root = ValOrErr->getAsObject();
  auto VersionOrErr = StubParser::getVersion(Root);
  if (!VersionOrErr)
    return VersionOrErr.takeError();
  FileType Version = *VersionOrErr;

  Object *MainLib = Root->getObject(Keys[TBDKey::MainLibrary]);
  auto IFOrErr = StubParser::parseToInterfaceFile(MainLib);
  if (!IFOrErr)
    return IFOrErr.takeError();
  (*IFOrErr)->setFileType(Version);
  std::unique_ptr<InterfaceFile> IF(std::move(*IFOrErr));

  auto IFsOrErr = StubParser::getInlinedLibs(Root);
  if (!IFsOrErr)
    return IFsOrErr.takeError();
  for (auto &File : *IFsOrErr) {
    File->setFileType(Version);
    IF->addDocument(std::shared_ptr<InterfaceFile>(std::move(File)));
  }
  return std::move(IF);
}

namespace {

template <typename ContainerT = Array>
bool insertNonEmptyValues(Object &Obj, TBDKey Key, ContainerT &&Contents) {
  if (Contents.empty())
    return false;
  Obj[Keys[Key]] = std::move(Contents);
  return true;
}

std::string getFormattedStr(const MachO::Target &Targ) {
  std::string PlatformStr = Targ.Platform == PLATFORM_MACCATALYST
                                ? "maccatalyst"
                                : getOSAndEnvironmentName(Targ.Platform);
  return (getArchitectureName(Targ.Arch) + "-" + PlatformStr).str();
}

template <typename AggregateT>
std::vector<std::string> serializeTargets(const AggregateT Targets,
                                          const TargetList &ActiveTargets) {
  std::vector<std::string> TargetsStr;
  if (Targets.size() == ActiveTargets.size())
    return TargetsStr;

  llvm::for_each(Targets, [&TargetsStr](const MachO::Target &Target) {
    TargetsStr.emplace_back(getFormattedStr(Target));
  });
  return TargetsStr;
}

Array serializeTargetInfo(const TargetList &ActiveTargets) {
  Array Targets;
  for (const auto Targ : ActiveTargets) {
    Object TargetInfo;
    TargetInfo[Keys[TBDKey::Deployment]] = Targ.MinDeployment.getAsString();
    TargetInfo[Keys[TBDKey::Target]] = getFormattedStr(Targ);
    Targets.emplace_back(std::move(TargetInfo));
  }
  return Targets;
}

template <typename ValueT, typename EntryT = ValueT>
Array serializeScalar(TBDKey Key, ValueT Value, ValueT Default = ValueT()) {
  if (Value == Default)
    return {};
  Array Container;
  Object ScalarObj({Object::KV({Keys[Key], EntryT(Value)})});

  Container.emplace_back(std::move(ScalarObj));
  return Container;
}

using TargetsToValuesMap =
    std::map<std::vector<std::string>, std::vector<std::string>>;

template <typename AggregateT = TargetsToValuesMap>
Array serializeAttrToTargets(AggregateT &Entries, TBDKey Key) {
  Array Container;
  for (const auto &[Targets, Values] : Entries) {
    Object Obj;
    insertNonEmptyValues(Obj, TBDKey::Targets, std::move(Targets));
    Obj[Keys[Key]] = Values;
    Container.emplace_back(std::move(Obj));
  }
  return Container;
}

template <typename ValueT = std::string,
          typename AggregateT = std::vector<std::pair<MachO::Target, ValueT>>>
Array serializeField(TBDKey Key, const AggregateT &Values,
                     const TargetList &ActiveTargets, bool IsArray = true) {
  std::map<ValueT, std::set<MachO::Target>> Entries;
  for (const auto &[Target, Val] : Values)
    Entries[Val].insert(Target);

  if (!IsArray) {
    std::map<std::vector<std::string>, std::string> FinalEntries;
    for (const auto &[Val, Targets] : Entries)
      FinalEntries[serializeTargets(Targets, ActiveTargets)] = Val;
    return serializeAttrToTargets(FinalEntries, Key);
  }

  TargetsToValuesMap FinalEntries;
  for (const auto &[Val, Targets] : Entries)
    FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(Val);
  return serializeAttrToTargets(FinalEntries, Key);
}

Array serializeField(TBDKey Key, const std::vector<InterfaceFileRef> &Values,
                     const TargetList &ActiveTargets) {
  TargetsToValuesMap FinalEntries;
  for (const auto &Ref : Values) {
    TargetList Targets{Ref.targets().begin(), Ref.targets().end()};
    FinalEntries[serializeTargets(Targets, ActiveTargets)].emplace_back(
        Ref.getInstallName());
  }
  return serializeAttrToTargets(FinalEntries, Key);
}

struct SymbolFields {
  struct SymbolTypes {
    std::vector<StringRef> Weaks;
    std::vector<StringRef> Globals;
    std::vector<StringRef> TLV;
    std::vector<StringRef> ObjCClasses;
    std::vector<StringRef> IVars;
    std::vector<StringRef> EHTypes;

    bool empty() const {
      return Weaks.empty() && Globals.empty() && TLV.empty() &&
             ObjCClasses.empty() && IVars.empty() && EHTypes.empty();
    }
  };
  SymbolTypes Data;
  SymbolTypes Text;
};

Array serializeSymbols(InterfaceFile::const_filtered_symbol_range Symbols,
                       const TargetList &ActiveTargets) {
  auto AssignForSymbolType = [](SymbolFields::SymbolTypes &Assignment,
                                const Symbol *Sym) {
    switch (Sym->getKind()) {
    case SymbolKind::ObjectiveCClass:
      Assignment.ObjCClasses.emplace_back(Sym->getName());
      return;
    case SymbolKind::ObjectiveCClassEHType:
      Assignment.EHTypes.emplace_back(Sym->getName());
      return;
    case SymbolKind::ObjectiveCInstanceVariable:
      Assignment.IVars.emplace_back(Sym->getName());
      return;
    case SymbolKind::GlobalSymbol: {
      if (Sym->isWeakReferenced() || Sym->isWeakDefined())
        Assignment.Weaks.emplace_back(Sym->getName());
      else if (Sym->isThreadLocalValue())
        Assignment.TLV.emplace_back(Sym->getName());
      else
        Assignment.Globals.emplace_back(Sym->getName());
      return;
    }
    }
  };

  std::map<std::vector<std::string>, SymbolFields> Entries;
  for (const auto *Sym : Symbols) {
    std::set<MachO::Target> Targets{Sym->targets().begin(),
                                    Sym->targets().end()};
    auto JSONTargets = serializeTargets(Targets, ActiveTargets);
    if (Sym->isData())
      AssignForSymbolType(Entries[std::move(JSONTargets)].Data, Sym);
    else if (Sym->isText())
      AssignForSymbolType(Entries[std::move(JSONTargets)].Text, Sym);
    else
      llvm_unreachable("unexpected symbol type");
  }

  auto InsertSymbolsToJSON = [](Object &SymSection, TBDKey SegmentKey,
                                SymbolFields::SymbolTypes &SymField) {
    if (SymField.empty())
      return;
    Object Segment;
    insertNonEmptyValues(Segment, TBDKey::Globals, std::move(SymField.Globals));
    insertNonEmptyValues(Segment, TBDKey::ThreadLocal, std::move(SymField.TLV));
    insertNonEmptyValues(Segment, TBDKey::Weak, std::move(SymField.Weaks));
    insertNonEmptyValues(Segment, TBDKey::ObjCClass,
                         std::move(SymField.ObjCClasses));
    insertNonEmptyValues(Segment, TBDKey::ObjCEHType,
                         std::move(SymField.EHTypes));
    insertNonEmptyValues(Segment, TBDKey::ObjCIvar, std::move(SymField.IVars));
    insertNonEmptyValues(SymSection, SegmentKey, std::move(Segment));
  };

  Array SymbolSection;
  for (auto &[Targets, Fields] : Entries) {
    Object AllSyms;
    insertNonEmptyValues(AllSyms, TBDKey::Targets, std::move(Targets));
    InsertSymbolsToJSON(AllSyms, TBDKey::Data, Fields.Data);
    InsertSymbolsToJSON(AllSyms, TBDKey::Text, Fields.Text);
    SymbolSection.emplace_back(std::move(AllSyms));
  }

  return SymbolSection;
}

Array serializeFlags(const InterfaceFile *File) {
  // TODO: Give all Targets the same flags for now.
  Array Flags;
  if (!File->isTwoLevelNamespace())
    Flags.emplace_back("flat_namespace");
  if (!File->isApplicationExtensionSafe())
    Flags.emplace_back("not_app_extension_safe");
  return serializeScalar(TBDKey::Attributes, std::move(Flags));
}

Expected<Object> serializeIF(const InterfaceFile *File) {
  Object Library;

  // Handle required keys.
  TargetList ActiveTargets{File->targets().begin(), File->targets().end()};
  if (!insertNonEmptyValues(Library, TBDKey::TargetInfo,
                            serializeTargetInfo(ActiveTargets)))
    return make_error<JSONStubError>(getSerializeErrorMsg(TBDKey::TargetInfo));

  Array Name = serializeScalar<StringRef>(TBDKey::Name, File->getInstallName());
  if (!insertNonEmptyValues(Library, TBDKey::InstallName, std::move(Name)))
    return make_error<JSONStubError>(getSerializeErrorMsg(TBDKey::InstallName));

  // Handle optional keys.
  Array Flags = serializeFlags(File);
  insertNonEmptyValues(Library, TBDKey::Flags, std::move(Flags));

  Array CurrentV = serializeScalar<PackedVersion, std::string>(
      TBDKey::Version, File->getCurrentVersion(), PackedVersion(1, 0, 0));
  insertNonEmptyValues(Library, TBDKey::CurrentVersion, std::move(CurrentV));

  Array CompatV = serializeScalar<PackedVersion, std::string>(
      TBDKey::Version, File->getCompatibilityVersion(), PackedVersion(1, 0, 0));
  insertNonEmptyValues(Library, TBDKey::CompatibilityVersion,
                       std::move(CompatV));

  Array SwiftABI = serializeScalar<uint8_t, int64_t>(
      TBDKey::ABI, File->getSwiftABIVersion(), 0u);
  insertNonEmptyValues(Library, TBDKey::SwiftABI, std::move(SwiftABI));

  Array RPaths = serializeField(TBDKey::Paths, File->rpaths(), ActiveTargets);
  insertNonEmptyValues(Library, TBDKey::RPath, std::move(RPaths));

  Array Umbrellas = serializeField(TBDKey::Umbrella, File->umbrellas(),
                                   ActiveTargets, /*IsArray=*/false);
  insertNonEmptyValues(Library, TBDKey::ParentUmbrella, std::move(Umbrellas));

  Array Clients =
      serializeField(TBDKey::Clients, File->allowableClients(), ActiveTargets);
  insertNonEmptyValues(Library, TBDKey::AllowableClients, std::move(Clients));

  Array ReexportLibs =
      serializeField(TBDKey::Names, File->reexportedLibraries(), ActiveTargets);
  insertNonEmptyValues(Library, TBDKey::ReexportLibs, std::move(ReexportLibs));

  // Handle symbols.
  Array Exports = serializeSymbols(File->exports(), ActiveTargets);
  insertNonEmptyValues(Library, TBDKey::Exports, std::move(Exports));

  Array Reexports = serializeSymbols(File->reexports(), ActiveTargets);
  insertNonEmptyValues(Library, TBDKey::Reexports, std::move(Reexports));

  if (!File->isTwoLevelNamespace()) {
    Array Undefineds = serializeSymbols(File->undefineds(), ActiveTargets);
    insertNonEmptyValues(Library, TBDKey::Undefineds, std::move(Undefineds));
  }

  return std::move(Library);
}

Expected<Object> getJSON(const InterfaceFile *File) {
  assert(File->getFileType() == FileType::TBD_V5 &&
         "unexpected json file format version");
  Object Root;

  auto MainLibOrErr = serializeIF(File);
  if (!MainLibOrErr)
    return MainLibOrErr;
  Root[Keys[TBDKey::MainLibrary]] = std::move(*MainLibOrErr);
  Array Documents;
  for (const auto &Doc : File->documents()) {
    auto LibOrErr = serializeIF(Doc.get());
    if (!LibOrErr)
      return LibOrErr;
    Documents.emplace_back(std::move(*LibOrErr));
  }

  Root[Keys[TBDKey::TBDVersion]] = 5;
  insertNonEmptyValues(Root, TBDKey::Documents, std::move(Documents));
  return std::move(Root);
}

} // namespace

Error MachO::serializeInterfaceFileToJSON(raw_ostream &OS,
                                          const InterfaceFile &File,
                                          bool Compact) {
  auto TextFile = getJSON(&File);
  if (!TextFile)
    return TextFile.takeError();
  if (Compact)
    OS << formatv("{0}", Value(std::move(*TextFile))) << "\n";
  else
    OS << formatv("{0:2}", Value(std::move(*TextFile))) << "\n";
  return Error::success();
}
