// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/mac/foundation_util.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/mac_logging.h"
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "build_config.h"

#if !defined(OS_IOS)
#import <AppKit/AppKit.h>
#endif

extern "C" {
CFTypeID SecKeyGetTypeID();
#if !defined(OS_IOS)
CFTypeID SecACLGetTypeID();
CFTypeID SecTrustedApplicationGetTypeID();
Boolean _CFIsObjC(CFTypeID typeID, CFTypeRef obj);
#endif
}  // extern "C"

namespace base {
namespace mac {

namespace {

bool g_cached_am_i_bundled_called = false;
bool g_cached_am_i_bundled_value = false;
bool g_override_am_i_bundled = false;
bool g_override_am_i_bundled_value = false;

bool UncachedAmIBundled() {
#if defined(OS_IOS)
  // All apps are bundled on iOS.
  return true;
#else
  if (g_override_am_i_bundled)
    return g_override_am_i_bundled_value;

  // Yes, this is cheap.
  return [[base::mac::OuterBundle() bundlePath] hasSuffix:@".app"];
#endif
}

}  // namespace

bool AmIBundled() {
  // If the return value is not cached, this function will return different
  // values depending on when it's called. This confuses some client code, see
  // http://crbug.com/63183 .
  if (!g_cached_am_i_bundled_called) {
    g_cached_am_i_bundled_called = true;
    g_cached_am_i_bundled_value = UncachedAmIBundled();
  }
  DCHECK_EQ(g_cached_am_i_bundled_value, UncachedAmIBundled())
      << "The return value of AmIBundled() changed. This will confuse tests. "
      << "Call SetAmIBundled() override manually if your test binary "
      << "delay-loads the framework.";
  return g_cached_am_i_bundled_value;
}

void SetOverrideAmIBundled(bool value) {
#if defined(OS_IOS)
  // It doesn't make sense not to be bundled on iOS.
  if (!value)
    NOTREACHED();
#endif
  g_override_am_i_bundled = true;
  g_override_am_i_bundled_value = value;
}

void ClearAmIBundledCache() {
  g_cached_am_i_bundled_called = false;
}

bool IsBackgroundOnlyProcess() {
  // This function really does want to examine NSBundle's idea of the main
  // bundle dictionary.  It needs to look at the actual running .app's
  // Info.plist to access its LSUIElement property.
  NSDictionary* info_dictionary = [base::mac::MainBundle() infoDictionary];
  return [info_dictionary[@"LSUIElement"] boolValue] != NO;
}

FilePath PathForFrameworkBundleResource(CFStringRef resourceName) {
  NSBundle* bundle = base::mac::FrameworkBundle();
  NSString* resourcePath =
      [bundle pathForResource:(NSString*)resourceName ofType:nil];
  return NSStringToFilePath(resourcePath);
}

OSType CreatorCodeForCFBundleRef(CFBundleRef bundle) {
  OSType creator = kUnknownType;
  CFBundleGetPackageInfo(bundle, NULL, &creator);
  return creator;
}

OSType CreatorCodeForApplication() {
  CFBundleRef bundle = CFBundleGetMainBundle();
  if (!bundle)
    return kUnknownType;

  return CreatorCodeForCFBundleRef(bundle);
}

bool GetSearchPathDirectory(NSSearchPathDirectory directory,
                            NSSearchPathDomainMask domain_mask,
                            FilePath* result) {
  DCHECK(result);
  NSArray<NSString*>* dirs =
      NSSearchPathForDirectoriesInDomains(directory, domain_mask, YES);
  if ([dirs count] < 1) {
    return false;
  }
  *result = NSStringToFilePath(dirs[0]);
  return true;
}

bool GetLocalDirectory(NSSearchPathDirectory directory, FilePath* result) {
  return GetSearchPathDirectory(directory, NSLocalDomainMask, result);
}

bool GetUserDirectory(NSSearchPathDirectory directory, FilePath* result) {
  return GetSearchPathDirectory(directory, NSUserDomainMask, result);
}

FilePath GetUserLibraryPath() {
  FilePath user_library_path;
  if (!GetUserDirectory(NSLibraryDirectory, &user_library_path)) {
    DLOG(WARNING) << "Could not get user library path";
  }
  return user_library_path;
}

// Takes a path to an (executable) binary and tries to provide the path to an
// application bundle containing it. It takes the outermost bundle that it can
// find (so for "/Foo/Bar.app/.../Baz.app/..." it produces "/Foo/Bar.app").
//   |exec_name| - path to the binary
//   returns - path to the application bundle, or empty on error
FilePath GetAppBundlePath(const FilePath& exec_name) {
  const char kExt[] = ".app";
  const size_t kExtLength = arraysize(kExt) - 1;

  // Split the path into components.
  std::vector<std::string> components;
  exec_name.GetComponents(&components);

  // It's an error if we don't get any components.
  if (components.empty())
    return FilePath();

  // Don't prepend '/' to the first component.
  std::vector<std::string>::const_iterator it = components.begin();
  std::string bundle_name = *it;
  DCHECK_GT(it->length(), 0U);
  // If the first component ends in ".app", we're already done.
  if (it->length() > kExtLength &&
      !it->compare(it->length() - kExtLength, kExtLength, kExt, kExtLength))
    return FilePath(bundle_name);

  // The first component may be "/" or "//", etc. Only append '/' if it doesn't
  // already end in '/'.
  if (bundle_name.back() != '/')
    bundle_name += '/';

  // Go through the remaining components.
  for (++it; it != components.end(); ++it) {
    DCHECK_GT(it->length(), 0U);

    bundle_name += *it;

    // If the current component ends in ".app", we're done.
    if (it->length() > kExtLength &&
        !it->compare(it->length() - kExtLength, kExtLength, kExt, kExtLength))
      return FilePath(bundle_name);

    // Separate this component from the next one.
    bundle_name += '/';
  }

  return FilePath();
}

#define TYPE_NAME_FOR_CF_TYPE_DEFN(TypeCF) \
  std::string TypeNameForCFType(TypeCF##Ref) { return #TypeCF; }

TYPE_NAME_FOR_CF_TYPE_DEFN(CFArray);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFBag);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFBoolean);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFData);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFDate);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFDictionary);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFNull);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFNumber);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFSet);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFString);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFURL);
TYPE_NAME_FOR_CF_TYPE_DEFN(CFUUID);

TYPE_NAME_FOR_CF_TYPE_DEFN(CGColor);

TYPE_NAME_FOR_CF_TYPE_DEFN(CTFont);
TYPE_NAME_FOR_CF_TYPE_DEFN(CTRun);

#if !defined(OS_IOS)
TYPE_NAME_FOR_CF_TYPE_DEFN(SecKey);
TYPE_NAME_FOR_CF_TYPE_DEFN(SecPolicy);
#endif

#undef TYPE_NAME_FOR_CF_TYPE_DEFN

void NSObjectRetain(void* obj) {
  id<NSObject> nsobj = static_cast<id<NSObject>>(obj);
  [nsobj retain];
}

void NSObjectRelease(void* obj) {
  id<NSObject> nsobj = static_cast<id<NSObject>>(obj);
  [nsobj release];
}

void* CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object) {
  // When GC is on, NSMakeCollectable marks cf_object for GC and autorelease
  // is a no-op.
  //
  // In the traditional GC-less environment, NSMakeCollectable is a no-op,
  // and cf_object is autoreleased, balancing out the caller's ownership claim.
  //
  // NSMakeCollectable returns nil when used on a NULL object.
  return [NSMakeCollectable(cf_object) autorelease];
}

static const char* base_bundle_id;

const char* BaseBundleID() {
  if (base_bundle_id) {
    return base_bundle_id;
  }

#if defined(GOOGLE_CHROME_BUILD)
  return "com.google.Chrome";
#else
  return "org.chromium.Chromium";
#endif
}

void SetBaseBundleID(const char* new_base_bundle_id) {
  if (new_base_bundle_id != base_bundle_id) {
    free((void*)base_bundle_id);
    base_bundle_id = new_base_bundle_id ? strdup(new_base_bundle_id) : NULL;
  }
}

// Definitions for the corresponding CF_TO_NS_CAST_DECL macros in
// foundation_util.h.
#define CF_TO_NS_CAST_DEFN(TypeCF, TypeNS)                            \
                                                                      \
  TypeNS* CFToNSCast(TypeCF##Ref cf_val) {                            \
    DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val));    \
    TypeNS* ns_val =                                                  \
        const_cast<TypeNS*>(reinterpret_cast<const TypeNS*>(cf_val)); \
    return ns_val;                                                    \
  }                                                                   \
                                                                      \
  TypeCF##Ref NSToCFCast(TypeNS* ns_val) {                            \
    TypeCF##Ref cf_val = reinterpret_cast<TypeCF##Ref>(ns_val);       \
    DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val));    \
    return cf_val;                                                    \
  }

#define CF_TO_NS_MUTABLE_CAST_DEFN(name)                                  \
  CF_TO_NS_CAST_DEFN(CF##name, NS##name)                                  \
                                                                          \
  NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val) {              \
    DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val));      \
    NSMutable##name* ns_val = reinterpret_cast<NSMutable##name*>(cf_val); \
    return ns_val;                                                        \
  }                                                                       \
                                                                          \
  CFMutable##name##Ref NSToCFCast(NSMutable##name* ns_val) {              \
    CFMutable##name##Ref cf_val =                                         \
        reinterpret_cast<CFMutable##name##Ref>(ns_val);                   \
    DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val));      \
    return cf_val;                                                        \
  }

CF_TO_NS_MUTABLE_CAST_DEFN(Array);
CF_TO_NS_MUTABLE_CAST_DEFN(AttributedString);
CF_TO_NS_CAST_DEFN(CFCalendar, NSCalendar);
CF_TO_NS_MUTABLE_CAST_DEFN(CharacterSet);
CF_TO_NS_MUTABLE_CAST_DEFN(Data);
CF_TO_NS_CAST_DEFN(CFDate, NSDate);
CF_TO_NS_MUTABLE_CAST_DEFN(Dictionary);
CF_TO_NS_CAST_DEFN(CFError, NSError);
CF_TO_NS_CAST_DEFN(CFLocale, NSLocale);
CF_TO_NS_CAST_DEFN(CFNumber, NSNumber);
CF_TO_NS_CAST_DEFN(CFRunLoopTimer, NSTimer);
CF_TO_NS_CAST_DEFN(CFTimeZone, NSTimeZone);
CF_TO_NS_MUTABLE_CAST_DEFN(Set);
CF_TO_NS_CAST_DEFN(CFReadStream, NSInputStream);
CF_TO_NS_CAST_DEFN(CFWriteStream, NSOutputStream);
CF_TO_NS_MUTABLE_CAST_DEFN(String);
CF_TO_NS_CAST_DEFN(CFURL, NSURL);

#if defined(OS_IOS)
CF_TO_NS_CAST_DEFN(CTFont, UIFont);
#else
// The NSFont/CTFont toll-free bridging is broken when it comes to type
// checking, so do some special-casing.
// http://www.openradar.me/15341349 rdar://15341349
NSFont* CFToNSCast(CTFontRef cf_val) {
  NSFont* ns_val = const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
  DCHECK(!cf_val || CTFontGetTypeID() == CFGetTypeID(cf_val) ||
         (_CFIsObjC(CTFontGetTypeID(), cf_val) &&
          [ns_val isKindOfClass:[NSFont class]]));
  return ns_val;
}

CTFontRef NSToCFCast(NSFont* ns_val) {
  CTFontRef cf_val = reinterpret_cast<CTFontRef>(ns_val);
  DCHECK(!cf_val || CTFontGetTypeID() == CFGetTypeID(cf_val) ||
         [ns_val isKindOfClass:[NSFont class]]);
  return cf_val;
}
#endif

#undef CF_TO_NS_CAST_DEFN
#undef CF_TO_NS_MUTABLE_CAST_DEFN

#define CF_CAST_DEFN(TypeCF)                                       \
  template <>                                                      \
  TypeCF##Ref CFCast<TypeCF##Ref>(const CFTypeRef& cf_val) {       \
    if (cf_val == NULL) {                                          \
      return NULL;                                                 \
    }                                                              \
    if (CFGetTypeID(cf_val) == TypeCF##GetTypeID()) {              \
      return (TypeCF##Ref)(cf_val);                                \
    }                                                              \
    return NULL;                                                   \
  }                                                                \
                                                                   \
  template <>                                                      \
  TypeCF##Ref CFCastStrict<TypeCF##Ref>(const CFTypeRef& cf_val) { \
    TypeCF##Ref rv = CFCast<TypeCF##Ref>(cf_val);                  \
    DCHECK(cf_val == NULL || rv);                                  \
    return rv;                                                     \
  }

CF_CAST_DEFN(CFArray);
CF_CAST_DEFN(CFBag);
CF_CAST_DEFN(CFBoolean);
CF_CAST_DEFN(CFData);
CF_CAST_DEFN(CFDate);
CF_CAST_DEFN(CFDictionary);
CF_CAST_DEFN(CFNull);
CF_CAST_DEFN(CFNumber);
CF_CAST_DEFN(CFSet);
CF_CAST_DEFN(CFString);
CF_CAST_DEFN(CFURL);
CF_CAST_DEFN(CFUUID);

CF_CAST_DEFN(CGColor);

CF_CAST_DEFN(CTFontDescriptor);
CF_CAST_DEFN(CTRun);

#if defined(OS_IOS)
CF_CAST_DEFN(CTFont);
#else
// The NSFont/CTFont toll-free bridging is broken when it comes to type
// checking, so do some special-casing.
// http://www.openradar.me/15341349 rdar://15341349
template <>
CTFontRef CFCast<CTFontRef>(const CFTypeRef& cf_val) {
  if (cf_val == NULL) {
    return NULL;
  }
  if (CFGetTypeID(cf_val) == CTFontGetTypeID()) {
    return (CTFontRef)(cf_val);
  }

  if (!_CFIsObjC(CTFontGetTypeID(), cf_val))
    return NULL;

  id<NSObject> ns_val = reinterpret_cast<id>(const_cast<void*>(cf_val));
  if ([ns_val isKindOfClass:[NSFont class]]) {
    return (CTFontRef)(cf_val);
  }
  return NULL;
}

template <>
CTFontRef CFCastStrict<CTFontRef>(const CFTypeRef& cf_val) {
  CTFontRef rv = CFCast<CTFontRef>(cf_val);
  DCHECK(cf_val == NULL || rv);
  return rv;
}
#endif

#if !defined(OS_IOS)
CF_CAST_DEFN(SecACL);
CF_CAST_DEFN(SecKey);
CF_CAST_DEFN(SecPolicy);
CF_CAST_DEFN(SecTrustedApplication);
#endif

#undef CF_CAST_DEFN

std::string GetValueFromDictionaryErrorMessage(CFStringRef key,
                                               const std::string& expected_type,
                                               CFTypeRef value) {
  ScopedCFTypeRef<CFStringRef> actual_type_ref(
      CFCopyTypeIDDescription(CFGetTypeID(value)));
  return "Expected value for key " + base::SysCFStringRefToUTF8(key) +
         " to be " + expected_type + " but it was " +
         base::SysCFStringRefToUTF8(actual_type_ref) + " instead";
}

NSString* FilePathToNSString(const FilePath& path) {
  if (path.empty())
    return nil;
  return @(path.value().c_str());  // @() does UTF8 conversion.
}

FilePath NSStringToFilePath(NSString* str) {
  if (![str length])
    return FilePath();
  return FilePath([str fileSystemRepresentation]);
}

bool CFRangeToNSRange(CFRange range, NSRange* range_out) {
  if (base::IsValueInRangeForNumericType<decltype(range_out->location)>(
          range.location) &&
      base::IsValueInRangeForNumericType<decltype(range_out->length)>(
          range.length) &&
      base::IsValueInRangeForNumericType<decltype(range_out->location)>(
          range.location + range.length)) {
    *range_out = NSMakeRange(range.location, range.length);
    return true;
  }
  return false;
}

}  // namespace mac
}  // namespace base

std::ostream& operator<<(std::ostream& o, const CFStringRef string) {
  return o << base::SysCFStringRefToUTF8(string);
}

std::ostream& operator<<(std::ostream& o, const CFErrorRef err) {
  base::ScopedCFTypeRef<CFStringRef> desc(CFErrorCopyDescription(err));
  base::ScopedCFTypeRef<CFDictionaryRef> user_info(CFErrorCopyUserInfo(err));
  CFStringRef errorDesc = NULL;
  if (user_info.get()) {
    errorDesc = reinterpret_cast<CFStringRef>(
        CFDictionaryGetValue(user_info.get(), kCFErrorDescriptionKey));
  }
  o << "Code: " << CFErrorGetCode(err) << " Domain: " << CFErrorGetDomain(err)
    << " Desc: " << desc.get();
  if (errorDesc) {
    o << "(" << errorDesc << ")";
  }
  return o;
}
