// 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 "chrome/browser/chrome_browser_main_mac.h"

#import <Cocoa/Cocoa.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/param.h>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/bundle_locations.h"
#import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/metrics/histogram_functions.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/threading/thread_task_runner_handle.h"
#import "chrome/browser/app_controller_mac.h"
#include "chrome/browser/apps/app_shim/app_shim_host_manager_mac.h"
#include "chrome/browser/browser_process.h"
#import "chrome/browser/chrome_browser_application_mac.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/first_run/upgrade_util_mac.h"
#include "chrome/browser/mac/install_from_dmg.h"
#import "chrome/browser/mac/keystone_glue.h"
#include "chrome/browser/mac/mac_startup_profiler.h"
#include "chrome/browser/ui/cocoa/main_menu_builder.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/mac/staging_watcher.h"
#include "chrome/grit/chromium_strings.h"
#include "components/crash/content/app/crashpad.h"
#include "components/metrics/metrics_service.h"
#include "components/os_crypt/os_crypt.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/result_codes.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_handle.h"
#include "ui/native_theme/native_theme_mac.h"

namespace {

// Writes an undocumented sentinel file that prevents Spotlight from indexing
// below a particular path in order to reap some power savings.
void EnsureMetadataNeverIndexFileOnFileThread(
    const base::FilePath& user_data_dir) {
  const char kMetadataNeverIndexFilename[] = ".metadata_never_index";
  base::FilePath metadata_file_path =
      user_data_dir.Append(kMetadataNeverIndexFilename);
  if (base::PathExists(metadata_file_path))
    return;

  if (base::WriteFile(metadata_file_path, nullptr, 0) == -1)
    DLOG(FATAL) << "Could not write .metadata_never_index file.";
}

void EnsureMetadataNeverIndexFile(const base::FilePath& user_data_dir) {
  base::PostTaskWithTraits(
      FROM_HERE,
      {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
       base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
      base::BindOnce(&EnsureMetadataNeverIndexFileOnFileThread, user_data_dir));
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class FilesystemType {
  kUnknown,
  kOther,
  k_acfs,
  k_afpfs,
  k_apfs,
  k_cdd9660,
  k_cddafs,
  k_exfat,
  k_ftp,
  k_hfs,
  k_hfs_rodmg,
  k_msdos,
  k_nfs,
  k_ntfs,
  k_smbfs,
  k_udf,
  k_webdav,
  kGoogleDriveFS,
  kMaxValue = kGoogleDriveFS,
};

FilesystemType FilesystemStringToType(DiskImageStatus is_ro_dmg,
                                      NSString* filesystem_type) {
  if ([filesystem_type isEqualToString:@"acfs"])
    return FilesystemType::k_acfs;
  if ([filesystem_type isEqualToString:@"afpfs"])
    return FilesystemType::k_afpfs;
  if ([filesystem_type isEqualToString:@"apfs"])
    return FilesystemType::k_apfs;
  if ([filesystem_type isEqualToString:@"cdd9660"])
    return FilesystemType::k_cdd9660;
  if ([filesystem_type isEqualToString:@"cddafs"])
    return FilesystemType::k_cddafs;
  if ([filesystem_type isEqualToString:@"exfat"])
    return FilesystemType::k_exfat;
  if ([filesystem_type isEqualToString:@"hfs"]) {
    switch (is_ro_dmg) {
      case DiskImageStatusFailure:
      case DiskImageStatusFalse:
        return FilesystemType::k_hfs;
        break;

      case DiskImageStatusTrue:
        return FilesystemType::k_hfs_rodmg;
        break;
    }
  }
  if ([filesystem_type isEqualToString:@"msdos"])
    return FilesystemType::k_msdos;
  if ([filesystem_type isEqualToString:@"nfs"])
    return FilesystemType::k_nfs;
  if ([filesystem_type isEqualToString:@"ntfs"])
    return FilesystemType::k_ntfs;
  if ([filesystem_type isEqualToString:@"smbfs"])
    return FilesystemType::k_smbfs;
  if ([filesystem_type isEqualToString:@"udf"])
    return FilesystemType::k_udf;
  if ([filesystem_type isEqualToString:@"webdav"])
    return FilesystemType::k_webdav;
  if ([filesystem_type isEqualToString:@"dfsfuse_DFS"])
    return FilesystemType::kGoogleDriveFS;
  return FilesystemType::kOther;
}

void RecordFilesystemStats() {
  DiskImageStatus is_ro_dmg = IsAppRunningFromReadOnlyDiskImage(nullptr);
  // Note that -getFileSystemInfoForPath:... is implemented with Disk
  // Arbitration and |filesystem_type_string| is the value from
  // kDADiskDescriptionVolumeKindKey. Furthermore, for built-in filesystems, the
  // string returned specifies which file in /System/Library/Filesystems is
  // handling it.
  NSString* filesystem_type_string;
  BOOL success = [[NSWorkspace sharedWorkspace]
      getFileSystemInfoForPath:[base::mac::OuterBundle() bundlePath]
                   isRemovable:nil
                    isWritable:nil
                 isUnmountable:nil
                   description:nil
                          type:&filesystem_type_string];

  FilesystemType filesystem_type = FilesystemType::kUnknown;
  if (success)
    filesystem_type = FilesystemStringToType(is_ro_dmg, filesystem_type_string);

  base::UmaHistogramEnumeration("OSX.InstallationFilesystem", filesystem_type);
}

void RecordInstanceStats() {
  upgrade_util::ThisAndOtherUserCounts counts =
      upgrade_util::GetCountOfOtherInstancesOfThisBinary();

  base::UmaHistogramCounts100("OSX.OtherInstances.ThisUser",
                              counts.this_user_count);
  base::UmaHistogramCounts100("OSX.OtherInstances.OtherUser",
                              counts.other_user_count);
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class FastUserSwitchEvent {
  kUserDidBecomeActiveEvent,
  kUserDidBecomeInactiveEvent,
  kMaxValue = kUserDidBecomeInactiveEvent,
};

void LogFastUserSwitchStat(FastUserSwitchEvent event) {
  base::UmaHistogramEnumeration("OSX.FastUserSwitch", event);
}

void InstallFastUserSwitchStatRecorder() {
  NSNotificationCenter* notification_center =
      [[NSWorkspace sharedWorkspace] notificationCenter];
  [notification_center
      addObserverForName:NSWorkspaceSessionDidBecomeActiveNotification
                  object:nil
                   queue:nil
              usingBlock:^(NSNotification* note) {
                LogFastUserSwitchStat(
                    FastUserSwitchEvent::kUserDidBecomeActiveEvent);
              }];
  [notification_center
      addObserverForName:NSWorkspaceSessionDidResignActiveNotification
                  object:nil
                   queue:nil
              usingBlock:^(NSNotification* note) {
                LogFastUserSwitchStat(
                    FastUserSwitchEvent::kUserDidBecomeInactiveEvent);
              }];
}

bool IsDirectoryWriteable(NSString* dir_path) {
  NSString* file_path = [dir_path stringByAppendingPathComponent:@"tempfile"];
  NSData* data = [NSData dataWithBytes:"\01\02\03\04\05" length:5];
  BOOL success = [data writeToFile:file_path atomically:NO];
  if (success)
    [[NSFileManager defaultManager] removeItemAtPath:file_path error:nil];

  return success;
}

bool IsOnSameFilesystemAsChromium(NSString* dir_path) {
  static const base::Optional<fsid_t> cr_fsid = []() -> base::Optional<fsid_t> {
    struct statfs buf;
    int result = statfs(
        [[base::mac::OuterBundle() bundlePath] fileSystemRepresentation], &buf);
    if (result != 0)
      return base::nullopt;
    return buf.f_fsid;
  }();

  if (!cr_fsid)
    return false;

  struct statfs buf;
  int result = statfs([dir_path fileSystemRepresentation], &buf);
  if (result != 0)
    return false;

  return cr_fsid->val[0] == buf.f_fsid.val[0] &&
         cr_fsid->val[1] == buf.f_fsid.val[1];
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class StagingDirectoryStep {
  kFailedToFindDirectory,
  kItemReplacementDirectory,
  kSiblingDirectory,
  kNSTemporaryDirectory,
  kTMPDIRDirectory,
  kTmpDirectory,
  kTmpDirectoryDifferentVolume,
  kMaxValue = kTmpDirectoryDifferentVolume,
};

void LogStagingDirectoryLocation(StagingDirectoryStep step) {
  base::UmaHistogramEnumeration("OSX.StagingDirectoryLocation2", step);
}

void RecordStagingDirectoryStats() {
  NSURL* bundle_url = [base::mac::OuterBundle() bundleURL];
  NSFileManager* file_manager = [NSFileManager defaultManager];

  // 1. A directory alongside Chromium.

  NSURL* bundle_parent_url =
      [[bundle_url URLByStandardizingPath] URLByDeletingLastPathComponent];
  NSURL* sibling_dir =
      [bundle_parent_url URLByAppendingPathComponent:@".GoogleChromeStaging"
                                         isDirectory:YES];
  NSString* sibling_dir_path = [sibling_dir path];

  BOOL is_directory;
  BOOL path_existed = [file_manager fileExistsAtPath:sibling_dir_path
                                         isDirectory:&is_directory];

  BOOL success = true;
  NSError* error = nil;
  if (!path_existed) {
    success = [file_manager createDirectoryAtURL:sibling_dir
                     withIntermediateDirectories:YES
                                      attributes:nil
                                           error:&error];
  } else if (!is_directory) {
    // There is a non-directory there; don't attempt to use this location
    // further.
    success = false;
  }

  if (success) {
    success &= !error && IsDirectoryWriteable(sibling_dir_path);

    // Only delete this directory if this was the code that created it.
    if (!path_existed)
      [file_manager removeItemAtURL:sibling_dir error:nil];
  }

  if (success) {
    LogStagingDirectoryLocation(StagingDirectoryStep::kSiblingDirectory);
    return;
  }

  // 2. NSItemReplacementDirectory

  error = nil;
  NSURL* item_replacement_dir =
      [file_manager URLForDirectory:NSItemReplacementDirectory
                           inDomain:NSUserDomainMask
                  appropriateForURL:bundle_url
                             create:YES
                              error:&error];
  if (item_replacement_dir && !error &&
      IsDirectoryWriteable([item_replacement_dir path])) {
    LogStagingDirectoryLocation(
        StagingDirectoryStep::kItemReplacementDirectory);
    return;
  }

  // 3. NSTemporaryDirectory()

  NSString* ns_temporary_dir = NSTemporaryDirectory();
  if (ns_temporary_dir && IsOnSameFilesystemAsChromium(ns_temporary_dir) &&
      IsDirectoryWriteable(ns_temporary_dir)) {
    LogStagingDirectoryLocation(StagingDirectoryStep::kNSTemporaryDirectory);
    return;
  }

  // 4. $TMPDIR

  const char* tmpdir_cstr = getenv("TMPDIR");
  NSString* tmpdir = tmpdir_cstr ? @(tmpdir_cstr) : nil;
  if (tmpdir && IsOnSameFilesystemAsChromium(tmpdir) &&
      IsDirectoryWriteable(tmpdir)) {
    LogStagingDirectoryLocation(StagingDirectoryStep::kTMPDIRDirectory);
    return;
  }

  // 5. /tmp

  NSString* tmp = @"/tmp";
  if (IsOnSameFilesystemAsChromium(tmp) && IsDirectoryWriteable(tmp)) {
    LogStagingDirectoryLocation(StagingDirectoryStep::kTmpDirectory);
    return;
  }

  // 6. /tmp, but different volume

  if (IsDirectoryWriteable(tmp)) {
    LogStagingDirectoryLocation(StagingDirectoryStep::kTmpDirectory);
    return;
  }

  // 7. Give up.

  LogStagingDirectoryLocation(StagingDirectoryStep::kFailedToFindDirectory);
}

// Records various bits of information about the local Chromium installation in
// UMA.
void RecordInstallationStats() {
  RecordFilesystemStats();
  RecordInstanceStats();
  InstallFastUserSwitchStatRecorder();
  RecordStagingDirectoryStats();
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class StartupUpdateState {
  kUpdateKeyNotSet,
  kUpdateKeySetAndStagedCopyPresent,
  kUpdateKeySetAndStagedCopyNotPresent,
  kMaxValue = kUpdateKeySetAndStagedCopyNotPresent,
};

// Records about the state of Chrome updates. This is pre-emptory data
// gathering to make sure that a situation that the team thinks will be OK is
// actually OK in the field.
void RecordUpdateState() {
  StartupUpdateState state = StartupUpdateState::kUpdateKeyNotSet;
  NSString* staging_location = [CrStagingKeyWatcher stagingLocation];
  if (staging_location) {
    if ([[NSFileManager defaultManager] fileExistsAtPath:staging_location])
      state = StartupUpdateState::kUpdateKeySetAndStagedCopyPresent;
    else
      state = StartupUpdateState::kUpdateKeySetAndStagedCopyNotPresent;
  }

  base::UmaHistogramEnumeration("OSX.StartupUpdateState", state);
}

}  // namespace

// ChromeBrowserMainPartsMac ---------------------------------------------------

ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac(
    const content::MainFunctionParams& parameters,
    StartupData* startup_data)
    : ChromeBrowserMainPartsPosix(parameters, startup_data) {}

ChromeBrowserMainPartsMac::~ChromeBrowserMainPartsMac() {
}

int ChromeBrowserMainPartsMac::PreEarlyInitialization() {
  if (base::mac::WasLaunchedAsLoginItemRestoreState()) {
    base::CommandLine* singleton_command_line =
        base::CommandLine::ForCurrentProcess();
    singleton_command_line->AppendSwitch(switches::kRestoreLastSession);
  } else if (base::mac::WasLaunchedAsHiddenLoginItem()) {
    base::CommandLine* singleton_command_line =
        base::CommandLine::ForCurrentProcess();
    singleton_command_line->AppendSwitch(switches::kNoStartupWindow);
  }

  return ChromeBrowserMainPartsPosix::PreEarlyInitialization();
}

void ChromeBrowserMainPartsMac::PreMainMessageLoopStart() {
  MacStartupProfiler::GetInstance()->Profile(
      MacStartupProfiler::PRE_MAIN_MESSAGE_LOOP_START);
  ChromeBrowserMainPartsPosix::PreMainMessageLoopStart();

  // ChromeBrowserMainParts should have loaded the resource bundle by this
  // point (needed to load the nib).
  CHECK(ui::ResourceBundle::HasSharedInstance());

  // This is a no-op if the KeystoneRegistration framework is not present.
  // The framework is only distributed with branded Google Chrome builds.
  [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone];

  // Disk image installation is sort of a first-run task, so it shares the
  // no first run switches.
  //
  // This needs to be done after the resource bundle is initialized (for
  // access to localizations in the UI) and after Keystone is initialized
  // (because the installation may need to promote Keystone) but before the
  // app controller is set up (and thus before MainMenu.nib is loaded, because
  // the app controller assumes that a browser has been set up and will crash
  // upon receipt of certain notifications if no browser exists), before
  // anyone tries doing anything silly like firing off an import job, and
  // before anything creating preferences like Local State in order for the
  // relaunched installed application to still consider itself as first-run.
  if (!first_run::IsFirstRunSuppressed(parsed_command_line())) {
    if (MaybeInstallFromDiskImage()) {
      // The application was installed and the installed copy has been
      // launched.  This process is now obsolete.  Exit.
      exit(0);
    }
  }

  // Create the app delegate. This object is intentionally leaked as a global
  // singleton. It is accessed through -[NSApp delegate].
  AppController* app_controller = [[AppController alloc] init];
  [NSApp setDelegate:app_controller];

  chrome::BuildMainMenu(NSApp, app_controller,
                        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), false);
  [app_controller mainMenuCreated];

  // Initialize the OSCrypt.
  PrefService* local_state = g_browser_process->local_state();
  DCHECK(local_state);
  OSCrypt::Init(local_state);
}

void ChromeBrowserMainPartsMac::PostMainMessageLoopStart() {
  MacStartupProfiler::GetInstance()->Profile(
      MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START);
  ChromeBrowserMainPartsPosix::PostMainMessageLoopStart();

  RecordInstallationStats();

  RecordUpdateState();
}

void ChromeBrowserMainPartsMac::PreProfileInit() {
  MacStartupProfiler::GetInstance()->Profile(
      MacStartupProfiler::PRE_PROFILE_INIT);
  ChromeBrowserMainPartsPosix::PreProfileInit();

  // This is called here so that the app shim socket is only created after
  // taking the singleton lock.
  g_browser_process->platform_part()->app_shim_host_manager()->Init();
}

void ChromeBrowserMainPartsMac::PostProfileInit() {
  MacStartupProfiler::GetInstance()->Profile(
      MacStartupProfiler::POST_PROFILE_INIT);
  ChromeBrowserMainPartsPosix::PostProfileInit();

  g_browser_process->metrics_service()->RecordBreakpadRegistration(
      crash_reporter::GetUploadsEnabled());

  if (first_run::IsChromeFirstRun())
    EnsureMetadataNeverIndexFile(user_data_dir());

  // Activation of Keystone is not automatic but done in response to the
  // counting and reporting of profiles.
  KeystoneGlue* glue = [KeystoneGlue defaultKeystoneGlue];
  if (glue && ![glue isRegisteredAndActive]) {
    // If profile loading has failed, we still need to handle other tasks
    // like marking of the product as active.
    [glue setRegistrationActive];
  }
}

void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
  AppController* appController =
      base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
  [appController didEndMainMessageLoop];
}
