//===- tools/dsymutil/CFBundle.cpp - CFBundle helper ------------*- 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 "CFBundle.h"

#ifdef __APPLE__
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
#include <glob.h>
#include <memory>
#endif

namespace llvm {
namespace dsymutil {

#ifdef __APPLE__
/// Deleter that calls CFRelease rather than deleting the pointer.
template <typename T> struct CFDeleter {
  void operator()(T *P) {
    if (P)
      ::CFRelease(P);
  }
};

/// This helper owns any CoreFoundation pointer and will call CFRelease() on
/// any valid pointer it owns unless that pointer is explicitly released using
/// the release() member function.
template <typename T>
using CFReleaser =
    std::unique_ptr<typename std::remove_pointer<T>::type,
                    CFDeleter<typename std::remove_pointer<T>::type>>;

/// RAII wrapper around CFBundleRef.
class CFString : public CFReleaser<CFStringRef> {
public:
  CFString(CFStringRef CFStr = nullptr) : CFReleaser<CFStringRef>(CFStr) {}

  const char *UTF8(std::string &Str) const {
    return CFString::UTF8(get(), Str);
  }

  CFIndex GetLength() const {
    if (CFStringRef Str = get())
      return CFStringGetLength(Str);
    return 0;
  }

  static const char *UTF8(CFStringRef CFStr, std::string &Str);
};

/// Static function that puts a copy of the UTF-8 contents of CFStringRef into
/// std::string and returns the C string pointer that is contained in the
/// std::string when successful, nullptr otherwise.
///
/// This allows the std::string parameter to own the extracted string, and also
/// allows that string to be returned as a C string pointer that can be used.
const char *CFString::UTF8(CFStringRef CFStr, std::string &Str) {
  if (!CFStr)
    return nullptr;

  const CFStringEncoding Encoding = kCFStringEncodingUTF8;
  CFIndex MaxUTF8StrLength = CFStringGetLength(CFStr);
  MaxUTF8StrLength =
      CFStringGetMaximumSizeForEncoding(MaxUTF8StrLength, Encoding);
  if (MaxUTF8StrLength > 0) {
    Str.resize(MaxUTF8StrLength);
    if (!Str.empty() &&
        CFStringGetCString(CFStr, &Str[0], Str.size(), Encoding)) {
      Str.resize(strlen(Str.c_str()));
      return Str.c_str();
    }
  }

  return nullptr;
}

/// RAII wrapper around CFBundleRef.
class CFBundle : public CFReleaser<CFBundleRef> {
public:
  CFBundle(StringRef Path) : CFReleaser<CFBundleRef>() { SetFromPath(Path); }

  CFBundle(CFURLRef Url)
      : CFReleaser<CFBundleRef>(Url ? ::CFBundleCreate(nullptr, Url)
                                    : nullptr) {}

  /// Return the bundle identifier.
  CFStringRef GetIdentifier() const {
    if (CFBundleRef bundle = get())
      return ::CFBundleGetIdentifier(bundle);
    return nullptr;
  }

  /// Return value for key.
  CFTypeRef GetValueForInfoDictionaryKey(CFStringRef key) const {
    if (CFBundleRef bundle = get())
      return ::CFBundleGetValueForInfoDictionaryKey(bundle, key);
    return nullptr;
  }

private:
  /// Helper to initialize this instance with a new bundle created from the
  /// given path. This function will recursively remove components from the
  /// path in its search for the nearest Info.plist.
  void SetFromPath(StringRef Path);
};

void CFBundle::SetFromPath(StringRef Path) {
  // Start from an empty/invalid CFBundle.
  reset();

  if (Path.empty() || !sys::fs::exists(Path))
    return;

  SmallString<256> RealPath;
  sys::fs::real_path(Path, RealPath, /*expand_tilde*/ true);

  do {
    // Create a CFURL from the current path and use it to create a CFBundle.
    CFReleaser<CFURLRef> BundleURL(::CFURLCreateFromFileSystemRepresentation(
        kCFAllocatorDefault, (const UInt8 *)RealPath.data(), RealPath.size(),
        false));
    reset(::CFBundleCreate(kCFAllocatorDefault, BundleURL.get()));

    // If we have a valid bundle and find its identifier we are done.
    if (get() != nullptr) {
      if (GetIdentifier() != nullptr)
        return;
      reset();
    }

    // Remove the last component of the path and try again until there's
    // nothing left but the root.
    sys::path::remove_filename(RealPath);
  } while (RealPath != sys::path::root_name(RealPath));
}
#endif

/// On Darwin, try and find the original executable's Info.plist to extract
/// information about the bundle. Return default values on other platforms.
CFBundleInfo getBundleInfo(StringRef ExePath) {
  CFBundleInfo BundleInfo;

#ifdef __APPLE__
  auto PrintError = [&](CFTypeID TypeID) {
    CFString TypeIDCFStr(::CFCopyTypeIDDescription(TypeID));
    std::string TypeIDStr;
    errs() << "The Info.plist key \"CFBundleShortVersionString\" is"
           << "a " << TypeIDCFStr.UTF8(TypeIDStr)
           << ", but it should be a string in: " << ExePath << ".\n";
  };

  CFBundle Bundle(ExePath);
  if (CFStringRef BundleID = Bundle.GetIdentifier()) {
    CFString::UTF8(BundleID, BundleInfo.IDStr);
    if (CFTypeRef TypeRef =
            Bundle.GetValueForInfoDictionaryKey(CFSTR("CFBundleVersion"))) {
      CFTypeID TypeID = ::CFGetTypeID(TypeRef);
      if (TypeID == ::CFStringGetTypeID())
        CFString::UTF8((CFStringRef)TypeRef, BundleInfo.VersionStr);
      else
        PrintError(TypeID);
    }
    if (CFTypeRef TypeRef = Bundle.GetValueForInfoDictionaryKey(
            CFSTR("CFBundleShortVersionString"))) {
      CFTypeID TypeID = ::CFGetTypeID(TypeRef);
      if (TypeID == ::CFStringGetTypeID())
        CFString::UTF8((CFStringRef)TypeRef, BundleInfo.ShortVersionStr);
      else
        PrintError(TypeID);
    }
  }
#endif

  return BundleInfo;
}

} // end namespace dsymutil
} // end namespace llvm
