//===--- Platform.cpp - Implement platform-related helpers ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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/Platform.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/VersionTuple.h"

using namespace swift;

bool swift::tripleIsiOSSimulator(const llvm::Triple &triple) {
  return (triple.isiOS() &&
          !tripleIsMacCatalystEnvironment(triple) &&
          triple.isSimulatorEnvironment());
}

bool swift::tripleIsAppleTVSimulator(const llvm::Triple &triple) {
  return (triple.isTvOS() && triple.isSimulatorEnvironment());
}

bool swift::tripleIsWatchSimulator(const llvm::Triple &triple) {
  return (triple.isWatchOS() && triple.isSimulatorEnvironment());
}

bool swift::tripleIsMacCatalystEnvironment(const llvm::Triple &triple) {
  return triple.isiOS() && !triple.isTvOS() &&
      triple.getEnvironment() == llvm::Triple::MacABI;
}

bool swift::tripleInfersSimulatorEnvironment(const llvm::Triple &triple) {
  switch (triple.getOS()) {
  case llvm::Triple::IOS:
  case llvm::Triple::TvOS:
  case llvm::Triple::WatchOS:
    return !triple.hasEnvironment() &&
        (triple.getArch() == llvm::Triple::x86 ||
         triple.getArch() == llvm::Triple::x86_64) &&
        !tripleIsMacCatalystEnvironment(triple);

  default:
    return false;
  }
}

bool swift::triplesAreValidForZippering(const llvm::Triple &target,
                                        const llvm::Triple &targetVariant) {
  // The arch and vendor must match.
  if (target.getArchName() != targetVariant.getArchName() ||
      target.getArch() != targetVariant.getArch() ||
      target.getSubArch() != targetVariant.getSubArch() ||
      target.getVendor() != targetVariant.getVendor()) {
    return false;
  }

  // Allow a macOS target and an iOS-macabi target variant
  // This is typically the case when zippering a library originally
  // developed for macOS.
  if (target.isMacOSX() && tripleIsMacCatalystEnvironment(targetVariant)) {
    return true;
  }

  // Allow an iOS-macabi target and a macOS target variant. This would
  // be the case when zippering a library originally developed for
  // iOS.
  if (targetVariant.isMacOSX() && tripleIsMacCatalystEnvironment(target)) {
    return true;
  }

  return false;
}

bool swift::tripleRequiresRPathForSwiftInOS(const llvm::Triple &triple) {
  if (triple.isMacOSX()) {
    // macOS 10.14.4 contains a copy of Swift, but the linker will still use an
    // rpath-based install name until 10.15.
    return triple.isMacOSXVersionLT(10, 15);
  }

  if (triple.isiOS()) {
    return triple.isOSVersionLT(12, 2);
  }

  if (triple.isWatchOS()) {
    return triple.isOSVersionLT(5, 2);
  }

  // Other platforms don't have Swift installed as part of the OS by default.
  return false;
}

DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) {
  if (triple.isiOS()) {
    if (triple.isTvOS()) {
      if (tripleIsAppleTVSimulator(triple))
        return DarwinPlatformKind::TvOSSimulator;
      return DarwinPlatformKind::TvOS;
    }

    if (tripleIsiOSSimulator(triple))
      return DarwinPlatformKind::IPhoneOSSimulator;
    return DarwinPlatformKind::IPhoneOS;
  }

  if (triple.isWatchOS()) {
    if (tripleIsWatchSimulator(triple))
      return DarwinPlatformKind::WatchOSSimulator;
    return DarwinPlatformKind::WatchOS;
  }

  if (triple.isMacOSX())
    return DarwinPlatformKind::MacOS;

  llvm_unreachable("Unsupported Darwin platform");
}

static StringRef getPlatformNameForDarwin(const DarwinPlatformKind platform) {
  switch (platform) {
  case DarwinPlatformKind::MacOS:
    return "macosx";
  case DarwinPlatformKind::IPhoneOS:
    return "iphoneos";
  case DarwinPlatformKind::IPhoneOSSimulator:
    return "iphonesimulator";
  case DarwinPlatformKind::TvOS:
    return "appletvos";
  case DarwinPlatformKind::TvOSSimulator:
    return "appletvsimulator";
  case DarwinPlatformKind::WatchOS:
    return "watchos";
  case DarwinPlatformKind::WatchOSSimulator:
    return "watchsimulator";
  }
  llvm_unreachable("Unsupported Darwin platform");
}

StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) {
  switch (triple.getOS()) {
  case llvm::Triple::UnknownOS:
    llvm_unreachable("unknown OS");
  case llvm::Triple::Ananas:
  case llvm::Triple::CloudABI:
  case llvm::Triple::DragonFly:
  case llvm::Triple::Emscripten:
  case llvm::Triple::Fuchsia:
  case llvm::Triple::KFreeBSD:
  case llvm::Triple::Lv2:
  case llvm::Triple::NetBSD:
  case llvm::Triple::Solaris:
  case llvm::Triple::Minix:
  case llvm::Triple::RTEMS:
  case llvm::Triple::NaCl:
  case llvm::Triple::CNK:
  case llvm::Triple::AIX:
  case llvm::Triple::CUDA:
  case llvm::Triple::NVCL:
  case llvm::Triple::AMDHSA:
  case llvm::Triple::ELFIAMCU:
  case llvm::Triple::Mesa3D:
  case llvm::Triple::Contiki:
  case llvm::Triple::AMDPAL:
  case llvm::Triple::HermitCore:
  case llvm::Triple::Hurd:
    return "";
  case llvm::Triple::Darwin:
  case llvm::Triple::MacOSX:
  case llvm::Triple::IOS:
  case llvm::Triple::TvOS:
  case llvm::Triple::WatchOS:
    return getPlatformNameForDarwin(getDarwinPlatformKind(triple));
  case llvm::Triple::Linux:
    return triple.isAndroid() ? "android" : "linux";
  case llvm::Triple::FreeBSD:
    return "freebsd";
  case llvm::Triple::OpenBSD:
    return "openbsd";
  case llvm::Triple::Win32:
    switch (triple.getEnvironment()) {
    case llvm::Triple::Cygnus:
      return "cygwin";
    case llvm::Triple::GNU:
      return "mingw";
    case llvm::Triple::MSVC:
    case llvm::Triple::Itanium:
      return "windows";
    default:
      llvm_unreachable("unsupported Windows environment");
    }
  case llvm::Triple::PS4:
    return "ps4";
  case llvm::Triple::Haiku:
    return "haiku";
  case llvm::Triple::WASI:
    return "wasi";
  }
  llvm_unreachable("unsupported OS");
}

StringRef swift::getMajorArchitectureName(const llvm::Triple &Triple) {
  if (Triple.isOSLinux()) {
    switch (Triple.getSubArch()) {
    case llvm::Triple::SubArchType::ARMSubArch_v7:
      return "armv7";
    case llvm::Triple::SubArchType::ARMSubArch_v6:
      return "armv6";
    default:
      break;
    }
  }
  return Triple.getArchName();
}

// The code below is responsible for normalizing target triples into the form
// used to name target-specific swiftmodule, swiftinterface, and swiftdoc files.
// If two triples have incompatible ABIs or can be distinguished by Swift #if
// declarations, they should normalize to different values.
//
// This code is only really used on platforms with toolchains supporting fat
// binaries (a single binary containing multiple architectures). On these
// platforms, this code should strip unnecessary details from target triple
// components and map synonyms to canonical values. Even values which don't need
// any special canonicalization should be documented here as comments.
//
// (Fallback behavior does not belong here; it should be implemented in code
// that calls this function, most importantly in SerializedModuleLoaderBase.)
//
// If you're trying to refer to this code to understand how Swift behaves and
// you're unfamiliar with LLVM internals, here's a cheat sheet for reading it:
//
// * llvm::Triple is the type for a target name. It's a bit of a misnomer,
//   because it can contain three or four values: arch-vendor-os[-environment].
//
// * In .Cases and .Case, the last argument is the value the arguments before it
//   map to. That is, `.Cases("bar", "baz", "foo")` will return "foo" if it sees
//   "bar" or "baz".
//
// * llvm::Optional is similar to a Swift Optional: it either contains a value
//   or represents the absence of one. `None` is equivalent to `nil`; leading
//   `*` is equivalent to trailing `!`; conversion to `bool` is a not-`None`
//   check.

static StringRef
getArchForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
  auto tripleArchName = triple.getArchName();

  return llvm::StringSwitch<StringRef>(tripleArchName)
              .Cases("arm64", "aarch64", "arm64")
              .Cases("x86_64", "amd64", "x86_64")
              .Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986",
                     "i386")
              .Cases("unknown", "", "unknown")
  // These values are also supported, but are handled by the default case below:
  //          .Case ("armv7s", "armv7s")
  //          .Case ("armv7k", "armv7k")
  //          .Case ("armv7", "armv7")
  //          .Case ("arm64e", "arm64e")
              .Default(tripleArchName);
}

static StringRef
getVendorForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
  // We unconditionally normalize to "apple" because it's relatively common for
  // build systems to omit the vendor name or use an incorrect one like
  // "unknown". Most parts of the compiler ignore the vendor, so you might not
  // notice such a mistake.
  //
  // Please don't depend on this behavior--specify 'apple' if you're building
  // for an Apple platform.

  assert(triple.isOSDarwin() &&
         "shouldn't normalize non-Darwin triple to 'apple'");

  return "apple";
}

static StringRef
getOSForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
  auto tripleOSName = triple.getOSName();

  // Truncate the OS name before the first digit. "Digit" here is ASCII '0'-'9'.
  auto tripleOSNameNoVersion = tripleOSName.take_until(llvm::isDigit);

  return llvm::StringSwitch<StringRef>(tripleOSNameNoVersion)
              .Cases("macos", "macosx", "darwin", "macos")
              .Cases("unknown", "", "unknown")
  // These values are also supported, but are handled by the default case below:
  //          .Case ("ios", "ios")
  //          .Case ("tvos", "tvos")
  //          .Case ("watchos", "watchos")
              .Default(tripleOSNameNoVersion);
}

static Optional<StringRef>
getEnvironmentForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) {
  auto tripleEnvironment = triple.getEnvironmentName();
  return llvm::StringSwitch<Optional<StringRef>>(tripleEnvironment)
              .Cases("unknown", "", None)
  // These values are also supported, but are handled by the default case below:
  //          .Case ("simulator", StringRef("simulator"))
  //          .Case ("macabi", StringRef("macabi"))
              .Default(tripleEnvironment);
}

llvm::Triple swift::getTargetSpecificModuleTriple(const llvm::Triple &triple) {
  // isOSDarwin() returns true for all Darwin-style OSes, including macOS, iOS,
  // etc.
  if (triple.isOSDarwin()) {
    StringRef newArch = getArchForAppleTargetSpecificModuleTriple(triple);

    StringRef newVendor = getVendorForAppleTargetSpecificModuleTriple(triple);

    StringRef newOS = getOSForAppleTargetSpecificModuleTriple(triple);

    Optional<StringRef> newEnvironment =
        getEnvironmentForAppleTargetSpecificModuleTriple(triple);

    if (!newEnvironment)
      // Generate an arch-vendor-os triple.
      return llvm::Triple(newArch, newVendor, newOS);

    // Generate an arch-vendor-os-environment triple.
    return llvm::Triple(newArch, newVendor, newOS, *newEnvironment);
  }

  // android - drop the API level.  That is not pertinent to the module; the API
  // availability is handled by the clang importer.
  if (triple.isAndroid()) {
    StringRef environment =
        llvm::Triple::getEnvironmentTypeName(triple.getEnvironment());

    return llvm::Triple(triple.getArchName(), triple.getVendorName(),
                        triple.getOSName(), environment);
  }

  // Other platforms get no normalization.
  return triple;
}

llvm::Triple swift::getUnversionedTriple(const llvm::Triple &triple) {
  StringRef unversionedOSName = triple.getOSName().take_until(llvm::isDigit);
  if (triple.getEnvironment()) {
    StringRef environment =
        llvm::Triple::getEnvironmentTypeName(triple.getEnvironment());

    return llvm::Triple(triple.getArchName(), triple.getVendorName(),
                        unversionedOSName, environment);
  }

  return llvm::Triple(triple.getArchName(), triple.getVendorName(),
                      unversionedOSName);
}

Optional<llvm::VersionTuple>
swift::getSwiftRuntimeCompatibilityVersionForTarget(
    const llvm::Triple &Triple) {
  unsigned Major, Minor, Micro;

  if (Triple.getArchName() == "arm64e")
    return llvm::VersionTuple(5, 3);

  if (Triple.isMacOSX()) {
    Triple.getMacOSXVersion(Major, Minor, Micro);
    if (Major == 10) {
      if (Triple.isAArch64() && Minor <= 16)
        return llvm::VersionTuple(5, 3);

      if (Minor <= 14) {
        return llvm::VersionTuple(5, 0);
      } else if (Minor <= 15) {
        if (Micro <= 3) {
          return llvm::VersionTuple(5, 1);
        } else {
          return llvm::VersionTuple(5, 2);
        }
      }
    } else if (Major == 11) {
      return llvm::VersionTuple(5, 3);
    }
  } else if (Triple.isiOS()) { // includes tvOS
    Triple.getiOSVersion(Major, Minor, Micro);

    // arm64 simulators and macCatalyst are introduced in iOS 14.0/tvOS 14.0
    // with Swift 5.3
    if (Triple.isAArch64() && Major <= 14 &&
        (Triple.isSimulatorEnvironment() || Triple.isMacCatalystEnvironment()))
      return llvm::VersionTuple(5, 3);

    if (Major <= 12) {
      return llvm::VersionTuple(5, 0);
    } else if (Major <= 13) {
      if (Minor <= 3) {
        return llvm::VersionTuple(5, 1);
      } else {
        return llvm::VersionTuple(5, 2);
      }
    }
  } else if (Triple.isWatchOS()) {
    Triple.getWatchOSVersion(Major, Minor, Micro);
    if (Major <= 5) {
      return llvm::VersionTuple(5, 0);
    } else if (Major <= 6) {
      if (Minor <= 1) {
        return llvm::VersionTuple(5, 1);
      } else {
        return llvm::VersionTuple(5, 2);
      }
    }
  }

  return None;
}


/// Remap the given version number via the version map, or produce \c None if
/// there is no mapping for this version.
static Optional<llvm::VersionTuple> remapVersion(
    const llvm::StringMap<llvm::VersionTuple> &versionMap,
    llvm::VersionTuple version) {
  // The build number is never used in the lookup.
  version = version.withoutBuild();

  // Look for this specific version.
  auto known = versionMap.find(version.getAsString());
  if (known != versionMap.end())
    return known->second;

  // If an extra ".0" was specified (in the subminor version), drop that
  // and look again.
  if (!version.getSubminor() || *version.getSubminor() != 0)
    return None;

  version = llvm::VersionTuple(version.getMajor(), *version.getMinor());
  known = versionMap.find(version.getAsString());
  if (known != versionMap.end())
    return known->second;

  // If another extra ".0" wa specified (in the minor version), drop that
  // and look again.
  if (!version.getMinor() || *version.getMinor() != 0)
    return None;

  version = llvm::VersionTuple(version.getMajor());
  known = versionMap.find(version.getAsString());
  if (known != versionMap.end())
    return known->second;

  return None;
}

llvm::VersionTuple
swift::getTargetSDKVersion(clang::driver::DarwinSDKInfo &SDKInfo,
                           const llvm::Triple &triple) {
  // Retrieve the SDK version.
  auto SDKVersion = SDKInfo.getVersion();

  // For the Mac Catalyst environment, we have a macOS SDK with a macOS
  // SDK version. Map that to the corresponding iOS version number to pass
  // down to the linker.
  if (tripleIsMacCatalystEnvironment(triple)) {
    return remapVersion(
        SDKInfo.getVersionMap().MacOS2iOSMacMapping, SDKVersion)
          .getValueOr(llvm::VersionTuple(0, 0, 0));
  }

  return SDKVersion;
}

static std::string getPlistEntry(const llvm::Twine &Path, StringRef KeyName) {
  auto BufOrErr = llvm::MemoryBuffer::getFile(Path);
  if (!BufOrErr) {
    // FIXME: diagnose properly
    return {};
  }

  std::string Key = "<key>";
  Key += KeyName;
  Key += "</key>";

  StringRef Lines = BufOrErr.get()->getBuffer();
  while (!Lines.empty()) {
    StringRef CurLine;
    std::tie(CurLine, Lines) = Lines.split('\n');
    if (CurLine.find(Key) != StringRef::npos) {
      std::tie(CurLine, Lines) = Lines.split('\n');
      unsigned Begin = CurLine.find("<string>") + strlen("<string>");
      unsigned End = CurLine.find("</string>");
      return CurLine.substr(Begin, End - Begin).str();
    }
  }

  return {};
}

std::string swift::getSDKBuildVersionFromPlist(StringRef Path) {
  return getPlistEntry(Path, "ProductBuildVersion");
}

std::string swift::getSDKBuildVersion(StringRef Path) {
  return getSDKBuildVersionFromPlist((llvm::Twine(Path) +
    "/System/Library/CoreServices/SystemVersion.plist").str());
}

std::string swift::getSDKName(StringRef Path) {
  std::string Name = getPlistEntry(llvm::Twine(Path)+"/SDKSettings.plist",
                                   "CanonicalName");
  if (Name.empty() && Path.endswith(".sdk")) {
    Name = llvm::sys::path::filename(Path).drop_back(strlen(".sdk")).str();
  }
  return Name;
}
