//===-- PlatformiOSSimulator.cpp -----------------------------------*- 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 "PlatformiOSSimulator.h"

#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

#include "llvm/Support/FileSystem.h"

using namespace lldb;
using namespace lldb_private;

namespace lldb_private {
class Process;
}

// Static Variables
static uint32_t g_initialize_count = 0;

// Static Functions
void PlatformiOSSimulator::Initialize() {
  PlatformAppleSimulator::Initialize();

  if (g_initialize_count++ == 0) {
    PluginManager::RegisterPlugin(PlatformiOSSimulator::GetPluginNameStatic(),
                                  PlatformiOSSimulator::GetDescriptionStatic(),
                                  PlatformiOSSimulator::CreateInstance);
  }
}

void PlatformiOSSimulator::Terminate() {
  if (g_initialize_count > 0) {
    if (--g_initialize_count == 0) {
      PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance);
    }
  }

  PlatformAppleSimulator::Terminate();
}

PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
                                                const ArchSpec *arch) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
  if (log) {
    const char *arch_name;
    if (arch && arch->GetArchitectureName())
      arch_name = arch->GetArchitectureName();
    else
      arch_name = "<null>";

    const char *triple_cstr =
        arch ? arch->GetTriple().getTriple().c_str() : "<null>";

    LLDB_LOGF(log, "PlatformiOSSimulator::%s(force=%s, arch={%s,%s})",
              __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
  }

  bool create = force;
  if (!create && arch && arch->IsValid()) {
    switch (arch->GetMachine()) {
    case llvm::Triple::x86_64:
    case llvm::Triple::x86: {
      const llvm::Triple &triple = arch->GetTriple();
      switch (triple.getVendor()) {
      case llvm::Triple::Apple:
        create = true;
        break;

#if defined(__APPLE__)
      // Only accept "unknown" for the vendor if the host is Apple and it
      // "unknown" wasn't specified (it was just returned because it was NOT
      // specified)
      case llvm::Triple::UnknownVendor:
        create = !arch->TripleVendorWasSpecified();
        break;
#endif
      default:
        break;
      }

      if (create) {
        switch (triple.getOS()) {
        case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
                                   // historical reasons
        case llvm::Triple::MacOSX:
        case llvm::Triple::IOS: // IOS is not used for simulator triples, but
                                // accept it just in case
          break;

#if defined(__APPLE__)
        // Only accept "unknown" for the OS if the host is Apple and it
        // "unknown" wasn't specified (it was just returned because it was NOT
        // specified)
        case llvm::Triple::UnknownOS:
          create = !arch->TripleOSWasSpecified();
          break;
#endif
        default:
          create = false;
          break;
        }
      }
    } break;
    default:
      break;
    }
  }
  if (create) {
    LLDB_LOGF(log, "PlatformiOSSimulator::%s() creating platform",
              __FUNCTION__);

    return PlatformSP(new PlatformiOSSimulator());
  }

  LLDB_LOGF(log, "PlatformiOSSimulator::%s() aborting creation of platform",
            __FUNCTION__);

  return PlatformSP();
}

lldb_private::ConstString PlatformiOSSimulator::GetPluginNameStatic() {
  static ConstString g_name("ios-simulator");
  return g_name;
}

const char *PlatformiOSSimulator::GetDescriptionStatic() {
  return "iOS simulator platform plug-in.";
}

/// Default Constructor
PlatformiOSSimulator::PlatformiOSSimulator()
    : PlatformAppleSimulator(), m_sdk_dir_mutex(), m_sdk_directory(),
      m_build_update() {}

/// Destructor.
///
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
PlatformiOSSimulator::~PlatformiOSSimulator() {}

void PlatformiOSSimulator::GetStatus(Stream &strm) {
  Platform::GetStatus(strm);
  const char *sdk_directory = GetSDKDirectoryAsCString();
  if (sdk_directory)
    strm.Printf("  SDK Path: \"%s\"\n", sdk_directory);
  else
    strm.PutCString("  SDK Path: error: unable to locate SDK\n");
  PlatformAppleSimulator::GetStatus(strm);
}

Status PlatformiOSSimulator::ResolveExecutable(
    const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
    const FileSpecList *module_search_paths_ptr) {
  Status error;
  // Nothing special to do here, just use the actual file and architecture

  ModuleSpec resolved_module_spec(module_spec);

  // If we have "ls" as the exe_file, resolve the executable loation based on
  // the current path variables
  // TODO: resolve bare executables in the Platform SDK
  //    if (!resolved_exe_file.Exists())
  //        resolved_exe_file.ResolveExecutableLocation ();

  // Resolve any executable within a bundle on MacOSX
  // TODO: verify that this handles shallow bundles, if not then implement one
  // ourselves
  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());

  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
    if (resolved_module_spec.GetArchitecture().IsValid()) {
      error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                          NULL, NULL, NULL);

      if (exe_module_sp && exe_module_sp->GetObjectFile())
        return error;
      exe_module_sp.reset();
    }
    // No valid architecture was specified or the exact ARM slice wasn't found
    // so ask the platform for the architectures that we should be using (in
    // the correct order) and see if we can find a match that way
    StreamString arch_names;
    ArchSpec platform_arch;
    for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
             idx, resolved_module_spec.GetArchitecture());
         ++idx) {
      // Only match x86 with x86 and x86_64 with x86_64...
      if (!module_spec.GetArchitecture().IsValid() ||
          module_spec.GetArchitecture().GetCore() ==
              resolved_module_spec.GetArchitecture().GetCore()) {
        error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                            NULL, NULL, NULL);
        // Did we find an executable using one of the
        if (error.Success()) {
          if (exe_module_sp && exe_module_sp->GetObjectFile())
            break;
          else
            error.SetErrorToGenericError();
        }

        if (idx > 0)
          arch_names.PutCString(", ");
        arch_names.PutCString(platform_arch.GetArchitectureName());
      }
    }

    if (error.Fail() || !exe_module_sp) {
      if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
        error.SetErrorStringWithFormat(
            "'%s' doesn't contain any '%s' platform architectures: %s",
            resolved_module_spec.GetFileSpec().GetPath().c_str(),
            GetPluginName().GetCString(), arch_names.GetString().str().c_str());
      } else {
        error.SetErrorStringWithFormat(
            "'%s' is not readable",
            resolved_module_spec.GetFileSpec().GetPath().c_str());
      }
    }
  } else {
    error.SetErrorStringWithFormat("'%s' does not exist",
                                   module_spec.GetFileSpec().GetPath().c_str());
  }

  return error;
}

static FileSystem::EnumerateDirectoryResult
EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
                           llvm::StringRef path) {
  if (ft == llvm::sys::fs::file_type::directory_file) {
    FileSpec file_spec(path);
    const char *filename = file_spec.GetFilename().GetCString();
    if (filename &&
        strncmp(filename, "iPhoneSimulator", strlen("iPhoneSimulator")) == 0) {
      ::snprintf((char *)baton, PATH_MAX, "%s", filename);
      return FileSystem::eEnumerateDirectoryResultQuit;
    }
  }
  return FileSystem::eEnumerateDirectoryResultNext;
}

const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
  std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
  if (m_sdk_directory.empty()) {
    const char *developer_dir = GetDeveloperDirectory();
    if (developer_dir) {
      char sdks_directory[PATH_MAX];
      char sdk_dirname[PATH_MAX];
      sdk_dirname[0] = '\0';
      snprintf(sdks_directory, sizeof(sdks_directory),
               "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs",
               developer_dir);
      FileSpec simulator_sdk_spec;
      bool find_directories = true;
      bool find_files = false;
      bool find_other = false;
      FileSystem::Instance().EnumerateDirectory(
          sdks_directory, find_directories, find_files, find_other,
          EnumerateDirectoryCallback, sdk_dirname);

      if (sdk_dirname[0]) {
        m_sdk_directory = sdks_directory;
        m_sdk_directory.append(1, '/');
        m_sdk_directory.append(sdk_dirname);
        return m_sdk_directory.c_str();
      }
    }
    // Assign a single NULL character so we know we tried to find the device
    // support directory and we don't keep trying to find it over and over.
    m_sdk_directory.assign(1, '\0');
  }

  // We should have put a single NULL character into m_sdk_directory or it
  // should have a valid path if the code gets here
  assert(m_sdk_directory.empty() == false);
  if (m_sdk_directory[0])
    return m_sdk_directory.c_str();
  return NULL;
}

Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
                                           const UUID *uuid_ptr,
                                           FileSpec &local_file) {
  Status error;
  char platform_file_path[PATH_MAX];
  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
    char resolved_path[PATH_MAX];

    const char *sdk_dir = GetSDKDirectoryAsCString();
    if (sdk_dir) {
      ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
                 platform_file_path);

      // First try in the SDK and see if the file is in there
      local_file.SetFile(resolved_path, FileSpec::Style::native);
      FileSystem::Instance().Resolve(local_file);
      if (FileSystem::Instance().Exists(local_file))
        return error;

      // Else fall back to the actual path itself
      local_file.SetFile(platform_file_path, FileSpec::Style::native);
      FileSystem::Instance().Resolve(local_file);
      if (FileSystem::Instance().Exists(local_file))
        return error;
    }
    error.SetErrorStringWithFormat(
        "unable to locate a platform file for '%s' in platform '%s'",
        platform_file_path, GetPluginName().GetCString());
  } else {
    error.SetErrorString("invalid platform file argument");
  }
  return error;
}

Status PlatformiOSSimulator::GetSharedModule(
    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
    const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
    bool *did_create_ptr) {
  // For iOS, the SDK files are all cached locally on the host system. So first
  // we ask for the file in the cached SDK, then we attempt to get a shared
  // module for the right architecture with the right UUID.
  Status error;
  ModuleSpec platform_module_spec(module_spec);
  const FileSpec &platform_file = module_spec.GetFileSpec();
  error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
                        platform_module_spec.GetFileSpec());
  if (error.Success()) {
    error = ResolveExecutable(platform_module_spec, module_sp,
                              module_search_paths_ptr);
  } else {
    const bool always_create = false;
    error = ModuleList::GetSharedModule(
        module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
        did_create_ptr, always_create);
  }
  if (module_sp)
    module_sp->SetPlatformFileSpec(platform_file);

  return error;
}

uint32_t
PlatformiOSSimulator::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                                    ProcessInstanceInfoList &process_infos) {
  ProcessInstanceInfoList all_osx_process_infos;
  // First we get all OSX processes
  const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);

  // Now we filter them down to only the iOS triples
  for (uint32_t i = 0; i < n; ++i) {
    const ProcessInstanceInfo &proc_info =
        all_osx_process_infos.GetProcessInfoAtIndex(i);
    if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) {
      process_infos.Append(proc_info);
    }
  }
  return process_infos.GetSize();
}

bool PlatformiOSSimulator::GetSupportedArchitectureAtIndex(uint32_t idx,
                                                           ArchSpec &arch) {
  static const ArchSpec platform_arch(
      HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
  static const ArchSpec platform_arch64(
      HostInfo::GetArchitecture(HostInfo::eArchKind64));

  if (idx == 0) {
    arch = platform_arch;
    if (arch.IsValid()) {
      arch.GetTriple().setOS(llvm::Triple::IOS);
      return true;
    }
  } else {
    if (platform_arch.IsExactMatch(platform_arch64)) {
      // This macosx platform supports both 32 and 64 bit.
      if (idx == 1) {
        // 32/64: return "x86_64-apple-macosx" for architecture 1
        arch = platform_arch64;
        return true;
      } else if (idx == 2 || idx == 3) {
        arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
        if (arch.IsValid()) {
          if (idx == 2)
            arch.GetTriple().setOS(llvm::Triple::IOS);
          // 32/64: return "i386-apple-ios" for architecture 2 32/64: return
          // "i386-apple-macosx" for architecture 3
          return true;
        }
      }
    } else if (idx == 1) {
      // This macosx platform supports only 32 bit, so return the *-apple-
      // macosx version
      arch = platform_arch;
      return true;
    }
  }
  return false;
}
