//===- TextStubCommon.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
//
//===----------------------------------------------------------------------===//
//
// Implememts common Text Stub YAML mappings.
//
//===----------------------------------------------------------------------===//

#include "TextStubCommon.h"
#include "TextAPIContext.h"
#include "llvm/ADT/StringSwitch.h"

using namespace llvm::MachO;

namespace llvm {
namespace yaml {

void ScalarTraits<FlowStringRef>::output(const FlowStringRef &Value, void *Ctx,
                                         raw_ostream &OS) {
  ScalarTraits<StringRef>::output(Value, Ctx, OS);
}
StringRef ScalarTraits<FlowStringRef>::input(StringRef Value, void *Ctx,
                                             FlowStringRef &Out) {
  return ScalarTraits<StringRef>::input(Value, Ctx, Out.value);
}
QuotingType ScalarTraits<FlowStringRef>::mustQuote(StringRef Name) {
  return ScalarTraits<StringRef>::mustQuote(Name);
}

void ScalarEnumerationTraits<ObjCConstraintType>::enumeration(
    IO &IO, ObjCConstraintType &Constraint) {
  IO.enumCase(Constraint, "none", ObjCConstraintType::None);
  IO.enumCase(Constraint, "retain_release", ObjCConstraintType::Retain_Release);
  IO.enumCase(Constraint, "retain_release_for_simulator",
              ObjCConstraintType::Retain_Release_For_Simulator);
  IO.enumCase(Constraint, "retain_release_or_gc",
              ObjCConstraintType::Retain_Release_Or_GC);
  IO.enumCase(Constraint, "gc", ObjCConstraintType::GC);
}

void ScalarTraits<PlatformSet>::output(const PlatformSet &Values, void *IO,
                                       raw_ostream &OS) {

  const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO);
  assert((!Ctx || Ctx->FileKind != FileType::Invalid) &&
         "File type is not set in context");

  if (Ctx && Ctx->FileKind == TBD_V3 && Values.count(PLATFORM_MACOS) &&
      Values.count(PLATFORM_MACCATALYST)) {
    OS << "zippered";
    return;
  }

  assert(Values.size() == 1U);
  switch (*Values.begin()) {
  default:
    llvm_unreachable("unexpected platform");
    break;
  case PLATFORM_MACOS:
    OS << "macosx";
    break;
  case PLATFORM_IOSSIMULATOR:
    [[fallthrough]];
  case PLATFORM_IOS:
    OS << "ios";
    break;
  case PLATFORM_WATCHOSSIMULATOR:
    [[fallthrough]];
  case PLATFORM_WATCHOS:
    OS << "watchos";
    break;
  case PLATFORM_TVOSSIMULATOR:
    [[fallthrough]];
  case PLATFORM_TVOS:
    OS << "tvos";
    break;
  case PLATFORM_BRIDGEOS:
    OS << "bridgeos";
    break;
  case PLATFORM_MACCATALYST:
    OS << "iosmac";
    break;
  case PLATFORM_DRIVERKIT:
    OS << "driverkit";
    break;
  }
}

StringRef ScalarTraits<PlatformSet>::input(StringRef Scalar, void *IO,
                                           PlatformSet &Values) {
  const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO);
  assert((!Ctx || Ctx->FileKind != FileType::Invalid) &&
         "File type is not set in context");

  if (Scalar == "zippered") {
    if (Ctx && Ctx->FileKind == FileType::TBD_V3) {
      Values.insert(PLATFORM_MACOS);
      Values.insert(PLATFORM_MACCATALYST);
      return {};
    }
    return "invalid platform";
  }

  auto Platform = StringSwitch<PlatformType>(Scalar)
                      .Case("macosx", PLATFORM_MACOS)
                      .Case("ios", PLATFORM_IOS)
                      .Case("watchos", PLATFORM_WATCHOS)
                      .Case("tvos", PLATFORM_TVOS)
                      .Case("bridgeos", PLATFORM_BRIDGEOS)
                      .Case("iosmac", PLATFORM_MACCATALYST)
                      .Case("driverkit", PLATFORM_DRIVERKIT)
                      .Default(PLATFORM_UNKNOWN);

  if (Platform == PLATFORM_MACCATALYST)
    if (Ctx && Ctx->FileKind != FileType::TBD_V3)
      return "invalid platform";

  if (Platform == PLATFORM_UNKNOWN)
    return "unknown platform";

  Values.insert(Platform);
  return {};
}

QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) {
  return QuotingType::None;
}

void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO,
                                                 ArchitectureSet &Archs) {
#define ARCHINFO(arch, type, subtype, numbits)                                 \
  IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch));
#include "llvm/TextAPI/Architecture.def"
#undef ARCHINFO
}

void ScalarTraits<Architecture>::output(const Architecture &Value, void *,
                                        raw_ostream &OS) {
  OS << Value;
}
StringRef ScalarTraits<Architecture>::input(StringRef Scalar, void *,
                                            Architecture &Value) {
  Value = getArchitectureFromName(Scalar);
  return {};
}
QuotingType ScalarTraits<Architecture>::mustQuote(StringRef) {
  return QuotingType::None;
}

void ScalarTraits<PackedVersion>::output(const PackedVersion &Value, void *,
                                         raw_ostream &OS) {
  OS << Value;
}
StringRef ScalarTraits<PackedVersion>::input(StringRef Scalar, void *,
                                             PackedVersion &Value) {
  if (!Value.parse32(Scalar))
    return "invalid packed version string.";
  return {};
}
QuotingType ScalarTraits<PackedVersion>::mustQuote(StringRef) {
  return QuotingType::None;
}

void ScalarTraits<SwiftVersion>::output(const SwiftVersion &Value, void *,
                                        raw_ostream &OS) {
  switch (Value) {
  case 1:
    OS << "1.0";
    break;
  case 2:
    OS << "1.1";
    break;
  case 3:
    OS << "2.0";
    break;
  case 4:
    OS << "3.0";
    break;
  default:
    OS << (unsigned)Value;
    break;
  }
}
StringRef ScalarTraits<SwiftVersion>::input(StringRef Scalar, void *IO,
                                            SwiftVersion &Value) {
  const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO);
  assert((!Ctx || Ctx->FileKind != FileType::Invalid) &&
         "File type is not set in context");

  if (Ctx->FileKind == FileType::TBD_V4) {
    if (Scalar.getAsInteger(10, Value))
      return "invalid Swift ABI version.";
    return {};
  } else {
    Value = StringSwitch<SwiftVersion>(Scalar)
                .Case("1.0", 1)
                .Case("1.1", 2)
                .Case("2.0", 3)
                .Case("3.0", 4)
                .Default(0);
  }

  if (Value != SwiftVersion(0))
    return {};

  if (Scalar.getAsInteger(10, Value))
    return "invalid Swift ABI version.";

  return StringRef();
}
QuotingType ScalarTraits<SwiftVersion>::mustQuote(StringRef) {
  return QuotingType::None;
}

void ScalarTraits<UUID>::output(const UUID &Value, void *, raw_ostream &OS) {
  OS << Value.first << ": " << Value.second;
}
StringRef ScalarTraits<UUID>::input(StringRef Scalar, void *, UUID &Value) {
  auto Split = Scalar.split(':');
  auto Arch = Split.first.trim();
  auto UUID = Split.second.trim();
  if (UUID.empty())
    return "invalid uuid string pair";
  Value.second = std::string(UUID);
  Value.first = Target{getArchitectureFromName(Arch), PLATFORM_UNKNOWN};
  return {};
}

QuotingType ScalarTraits<UUID>::mustQuote(StringRef) {
  return QuotingType::Single;
}

} // end namespace yaml.
} // end namespace llvm.
