//===-- HostInfoMacOSX.mm ---------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include "Utility/UuidCompatibility.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

// C++ Includes
#include <string>

// C inclues
#include <cstdlib>
#include <sys/sysctl.h>
#include <sys/syslimits.h>
#include <sys/types.h>

// Objective-C/C++ includes
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
#include <mach-o/dyld.h>
#include <objc/objc-auto.h>

// These are needed when compiling on systems
// that do not yet have these definitions
#include <AvailabilityMacros.h>
#ifndef CPU_SUBTYPE_X86_64_H
#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8)
#endif
#ifndef CPU_TYPE_ARM64
#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
#endif

#ifndef CPU_TYPE_ARM64_32
#define CPU_ARCH_ABI64_32 0x02000000
#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32)
#endif

#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH

using namespace lldb_private;

llvm::Optional<std::string> HostInfoMacOSX::GetOSBuildString() {
  int mib[2] = {CTL_KERN, KERN_OSVERSION};
  char cstr[PATH_MAX];
  size_t cstr_len = sizeof(cstr);
  if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0)
    return std::string(cstr, cstr_len - 1);

  return llvm::None;
}

static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
  @autoreleasepool {
    NSDictionary *version_info =
      [NSDictionary dictionaryWithContentsOfFile:
       @"/System/Library/CoreServices/SystemVersion.plist"];
    NSString *version_value = [version_info objectForKey: Key];
    const char *version_str = [version_value UTF8String];
    version.tryParse(version_str);
  }
}

llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
  static llvm::VersionTuple g_version;
  if (g_version.empty())
    ParseOSVersion(g_version, @"ProductVersion");
  return g_version;
}

llvm::VersionTuple HostInfoMacOSX::GetMacCatalystVersion() {
  static llvm::VersionTuple g_version;
  if (g_version.empty())
    ParseOSVersion(g_version, @"iOSSupportVersion");
  return g_version;
}


FileSpec HostInfoMacOSX::GetProgramFileSpec() {
  static FileSpec g_program_filespec;
  if (!g_program_filespec) {
    char program_fullpath[PATH_MAX];
    // If DST is NULL, then return the number of bytes needed.
    uint32_t len = sizeof(program_fullpath);
    int err = _NSGetExecutablePath(program_fullpath, &len);
    if (err == 0)
      g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native);
    else if (err == -1) {
      char *large_program_fullpath = (char *)::malloc(len + 1);

      err = _NSGetExecutablePath(large_program_fullpath, &len);
      if (err == 0)
        g_program_filespec.SetFile(large_program_fullpath,
                                   FileSpec::Style::native);

      ::free(large_program_fullpath);
    }
  }
  return g_program_filespec;
}

bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos != std::string::npos) {
    framework_pos += strlen("LLDB.framework");
#if TARGET_OS_IPHONE
    // Shallow bundle
    raw_path.resize(framework_pos);
#else
    // Normal bundle
    raw_path.resize(framework_pos);
    raw_path.append("/Resources");
#endif
  } else {
    // Find the bin path relative to the lib path where the cmake-based
    // OS X .dylib lives.  This is not going to work if the bin and lib
    // dir are not both in the same dir.
    //
    // It is not going to work to do it by the executable path either,
    // as in the case of a python script, the executable is python, not
    // the lldb driver.
    raw_path.append("/../bin");
    FileSpec support_dir_spec(raw_path);
    FileSystem::Instance().Resolve(support_dir_spec);
    if (!FileSystem::Instance().IsDirectory(support_dir_spec)) {
      Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
      LLDB_LOGF(log, "HostInfoMacOSX::%s(): failed to find support directory",
                __FUNCTION__);
      return false;
    }

    // Get normalization from support_dir_spec.  Note the FileSpec resolve
    // does not remove '..' in the path.
    char *const dir_realpath =
        realpath(support_dir_spec.GetPath().c_str(), NULL);
    if (dir_realpath) {
      raw_path = dir_realpath;
      free(dir_realpath);
    } else {
      raw_path = support_dir_spec.GetPath();
    }
  }

  file_spec.GetDirectory().SetString(
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
  return (bool)file_spec.GetDirectory();
}

bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos != std::string::npos) {
    framework_pos += strlen("LLDB.framework");
    raw_path.resize(framework_pos);
    raw_path.append("/Headers");
  }
  file_spec.GetDirectory().SetString(
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
  return true;
}

bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos == std::string::npos)
    return false;

  framework_pos += strlen("LLDB.framework");
  raw_path.resize(framework_pos);
  raw_path.append("/Resources/PlugIns");
  file_spec.GetDirectory().SetString(
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
  return true;
}

bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
  FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
  FileSystem::Instance().Resolve(temp_file);
  file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
  return true;
}

void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
                                                    ArchSpec &arch_64) {
  // All apple systems support 32 bit execution.
  uint32_t cputype, cpusubtype;
  uint32_t is_64_bit_capable = false;
  size_t len = sizeof(cputype);
  ArchSpec host_arch;
  // These will tell us about the kernel architecture, which even on a 64
  // bit machine can be 32 bit...
  if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) {
    len = sizeof(cpusubtype);
    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
      cpusubtype = CPU_TYPE_ANY;

    len = sizeof(is_64_bit_capable);
    ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);

    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
      // The arm64e architecture is a preview. Pretend the host architecture
      // is arm64.
      cpusubtype = CPU_SUBTYPE_ARM64_ALL;
    }

    if (is_64_bit_capable) {
      if (cputype & CPU_ARCH_ABI64) {
        // We have a 64 bit kernel on a 64 bit system
        arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
      } else {
        // We have a 64 bit kernel that is returning a 32 bit cputype, the
        // cpusubtype will be correct as if it were for a 64 bit architecture
        arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64,
                                cpusubtype);
      }

      // Now we need modify the cpusubtype for the 32 bit slices.
      uint32_t cpusubtype32 = cpusubtype;
#if defined(__i386__) || defined(__x86_64__)
      if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H)
        cpusubtype32 = CPU_SUBTYPE_I386_ALL;
#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
      if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
        cpusubtype32 = CPU_SUBTYPE_ARM_V7S;
#endif
      arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK),
                              cpusubtype32);

      if (cputype == CPU_TYPE_ARM || 
          cputype == CPU_TYPE_ARM64 || 
          cputype == CPU_TYPE_ARM64_32) {
// When running on a watch or tv, report the host os correctly
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
        arch_32.GetTriple().setOS(llvm::Triple::TvOS);
        arch_64.GetTriple().setOS(llvm::Triple::TvOS);
#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
        arch_32.GetTriple().setOS(llvm::Triple::BridgeOS);
        arch_64.GetTriple().setOS(llvm::Triple::BridgeOS);
#elif defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS == 1
        arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
        arch_64.GetTriple().setOS(llvm::Triple::WatchOS);
#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
#else
        arch_32.GetTriple().setOS(llvm::Triple::IOS);
        arch_64.GetTriple().setOS(llvm::Triple::IOS);
#endif
      } else {
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
      }
    } else {
      // We have a 32 bit kernel on a 32 bit system
      arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
      arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
#else
      arch_32.GetTriple().setOS(llvm::Triple::IOS);
#endif
      arch_64.Clear();
    }
  }
}

/// Return and cache $DEVELOPER_DIR if it is set and exists.
static std::string GetEnvDeveloperDir() {
  static std::string g_env_developer_dir;
  static std::once_flag g_once_flag;
  std::call_once(g_once_flag, [&]() {
    if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) {
      FileSpec fspec(developer_dir_env_var);
      if (FileSystem::Instance().Exists(fspec))
        g_env_developer_dir = fspec.GetPath();
    }});
  return g_env_developer_dir;
}

FileSpec HostInfoMacOSX::GetXcodeContentsDirectory() {
  static FileSpec g_xcode_contents_path;
  static std::once_flag g_once_flag;
  std::call_once(g_once_flag, [&]() {
    // Try the shlib dir first.
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string xcode_contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        if (!xcode_contents_dir.empty()) {
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
          return;
        }
      }
    }

    llvm::SmallString<128> env_developer_dir(GetEnvDeveloperDir());
    if (!env_developer_dir.empty()) {
      llvm::sys::path::append(env_developer_dir, "Contents");
      std::string xcode_contents_dir =
          XcodeSDK::FindXcodeContentsDirectoryInPath(env_developer_dir);
      if (!xcode_contents_dir.empty()) {
        g_xcode_contents_path = FileSpec(xcode_contents_dir);
        return;
      }
    }

    FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS()));
    if (fspec) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string xcode_contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        if (!xcode_contents_dir.empty()) {
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
          return;
        }
      }
    }
  });
  return g_xcode_contents_path;
}

lldb_private::FileSpec HostInfoMacOSX::GetXcodeDeveloperDirectory() {
  static lldb_private::FileSpec g_developer_directory;
  static llvm::once_flag g_once_flag;
  llvm::call_once(g_once_flag, []() {
    if (FileSpec fspec = GetXcodeContentsDirectory()) {
      fspec.AppendPathComponent("Developer");
      if (FileSystem::Instance().Exists(fspec))
        g_developer_directory = fspec;
    }
  });
  return g_developer_directory;
}

static std::string GetXcodeSDK(XcodeSDK sdk) {
  XcodeSDK::Info info = sdk.Parse();
  std::string sdk_name = XcodeSDK::GetCanonicalName(info);

  auto xcrun = [](const std::string &sdk,
                  llvm::StringRef developer_dir = "") -> std::string {
    Args args;
    if (!developer_dir.empty()) {
      args.AppendArgument("/usr/bin/env");
      args.AppendArgument("DEVELOPER_DIR=" + developer_dir.str());
    }
    args.AppendArgument("/usr/bin/xcrun");
    args.AppendArgument("--show-sdk-path");
    args.AppendArgument("--sdk");
    args.AppendArgument(sdk);

    int status = 0;
    int signo = 0;
    std::string output_str;
    lldb_private::Status error =
        Host::RunShellCommand(args, FileSpec(), &status, &signo, &output_str,
                              std::chrono::seconds(15));

    // Check that xcrun return something useful.
    if (status != 0 || output_str.empty())
      return {};

    // Convert to a StringRef so we can manipulate the string without modifying
    // the underlying data.
    llvm::StringRef output(output_str);

    // Remove any trailing newline characters.
    output = output.rtrim();

    // Strip any leading newline characters and everything before them.
    const size_t last_newline = output.rfind('\n');
    if (last_newline != llvm::StringRef::npos)
      output = output.substr(last_newline + 1);

    return output.str();
  };

  auto find_sdk = [&xcrun](const std::string &sdk_name) -> std::string {
    // Invoke xcrun with the developer dir specified in the environment.
    std::string developer_dir = GetEnvDeveloperDir();
    if (!developer_dir.empty()) {
      // Don't fallback if DEVELOPER_DIR was set.
      return xcrun(sdk_name, developer_dir);
    }

    // Invoke xcrun with the shlib dir.
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        llvm::StringRef shlib_developer_dir =
            llvm::sys::path::parent_path(contents_dir);
        if (!shlib_developer_dir.empty()) {
          std::string sdk = xcrun(sdk_name, std::move(shlib_developer_dir));
          if (!sdk.empty())
            return sdk;
        }
      }
    }

    // Invoke xcrun without a developer dir as a last resort.
    return xcrun(sdk_name);
  };

  std::string path = find_sdk(sdk_name);
  while (path.empty()) {
    // Try an alternate spelling of the name ("macosx10.9internal").
    if (info.type == XcodeSDK::Type::MacOSX && !info.version.empty() &&
        info.internal) {
      llvm::StringRef fixed(sdk_name);
      if (fixed.consume_back(".internal"))
        sdk_name = fixed.str() + "internal";
      path = find_sdk(sdk_name);
      if (!path.empty())
        break;
    }
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
    LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str());

    // Try without the version.
    if (!info.version.empty()) {
      info.version = {};
      sdk_name = XcodeSDK::GetCanonicalName(info);
      path = find_sdk(sdk_name);
      if (!path.empty())
        break;
    }

    LLDB_LOGF(log, "Couldn't find any matching SDK on host");
    return {};
  }

  // Whatever is left in output should be a valid path.
  if (!FileSystem::Instance().Exists(path))
    return {};
  return path;
}

llvm::StringRef HostInfoMacOSX::GetXcodeSDKPath(XcodeSDK sdk) {
  static llvm::StringMap<std::string> g_sdk_path;
  static std::mutex g_sdk_path_mutex;

  std::lock_guard<std::mutex> guard(g_sdk_path_mutex);
  LLDB_SCOPED_TIMER();

  auto it = g_sdk_path.find(sdk.GetString());
  if (it != g_sdk_path.end())
    return it->second;
  auto it_new = g_sdk_path.insert({sdk.GetString(), GetXcodeSDK(sdk)});
  return it_new.first->second;
}

namespace {
struct dyld_shared_cache_dylib_text_info {
  uint64_t version; // current version 1
  // following fields all exist in version 1
  uint64_t loadAddressUnslid;
  uint64_t textSegmentSize;
  uuid_t dylibUuid;
  const char *path; // pointer invalid at end of iterations
  // following fields all exist in version 2
  uint64_t textSegmentOffset; // offset from start of cache
};
typedef struct dyld_shared_cache_dylib_text_info
    dyld_shared_cache_dylib_text_info;
}

extern "C" int dyld_shared_cache_iterate_text(
    const uuid_t cacheUuid,
    void (^callback)(const dyld_shared_cache_dylib_text_info *info));
extern "C" uint8_t *_dyld_get_shared_cache_range(size_t *length);
extern "C" bool _dyld_get_shared_cache_uuid(uuid_t uuid);

namespace {
class SharedCacheInfo {
public:
  const UUID &GetUUID() const { return m_uuid; }
  const llvm::StringMap<SharedCacheImageInfo> &GetImages() const {
    return m_images;
  }

  SharedCacheInfo();

private:
  llvm::StringMap<SharedCacheImageInfo> m_images;
  UUID m_uuid;
};
}

SharedCacheInfo::SharedCacheInfo() {
  size_t shared_cache_size;
  uint8_t *shared_cache_start =
      _dyld_get_shared_cache_range(&shared_cache_size);
  uuid_t dsc_uuid;
  _dyld_get_shared_cache_uuid(dsc_uuid);
  m_uuid = UUID::fromData(dsc_uuid);

  dyld_shared_cache_iterate_text(
      dsc_uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
        m_images[info->path] = SharedCacheImageInfo{
            UUID::fromData(info->dylibUuid, 16),
            std::make_shared<DataBufferUnowned>(
                shared_cache_start + info->textSegmentOffset,
                shared_cache_size - info->textSegmentOffset)};
      });
}

SharedCacheImageInfo
HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
  static SharedCacheInfo g_shared_cache_info;
  return g_shared_cache_info.GetImages().lookup(image_name);
}
