//===- tools/dsymutil/CFBundle.cpp - CFBundle helper ------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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
