// 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.

#import <Foundation/Foundation.h>
#include <launch.h>

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/scoped_nsobject.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/version.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/mac/launchd.h"
#include "chrome/common/service_process_util_posix.h"
#include "components/version_info/version_info.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"

@interface NSFileManager (YosemiteSDK)
- (BOOL)getRelationship:(NSURLRelationship*)outRelationship
            ofDirectory:(NSSearchPathDirectory)directory
               inDomain:(NSSearchPathDomainMask)domainMask
            toItemAtURL:(NSURL*)url
                  error:(NSError**)error;
@end

using ::base::FilePathWatcher;

namespace {

#define kServiceProcessSessionType "Aqua"

CFStringRef CopyServiceProcessLaunchDName() {
  base::mac::ScopedNSAutoreleasePool pool;
  NSBundle* bundle = base::mac::FrameworkBundle();
  return CFStringCreateCopy(kCFAllocatorDefault,
                            base::mac::NSToCFCast([bundle bundleIdentifier]));
}

NSString* GetServiceProcessLaunchDLabel() {
  base::scoped_nsobject<NSString> name(
      base::mac::CFToNSCast(CopyServiceProcessLaunchDName()));
  NSString* label = [name stringByAppendingString:@".service_process"];
  base::FilePath user_data_dir;
  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  std::string user_data_dir_path = user_data_dir.value();
  NSString* ns_path = base::SysUTF8ToNSString(user_data_dir_path);
  ns_path = [ns_path stringByReplacingOccurrencesOfString:@" "
                                               withString:@"_"];
  label = [label stringByAppendingString:ns_path];
  return label;
}

NSString* GetServiceProcessLaunchDSocketKey() {
  return @"ServiceProcessSocket";
}

bool RemoveFromLaunchd() {
  // We're killing a file.
  base::ThreadRestrictions::AssertIOAllowed();
  base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
  return Launchd::GetInstance()->DeletePlist(Launchd::User,
                                             Launchd::Agent,
                                             name);
}

class ExecFilePathWatcherCallback {
 public:
  ExecFilePathWatcherCallback() {}
  ~ExecFilePathWatcherCallback() {}

  bool Init(const base::FilePath& path);
  void NotifyPathChanged(const base::FilePath& path, bool error);

 private:
  base::scoped_nsobject<NSURL> executable_fsref_;
};

base::FilePath GetServiceProcessSocketName() {
  base::FilePath socket_name;
  PathService::Get(base::DIR_TEMP, &socket_name);
  std::string pipe_name = GetServiceProcessScopedName("srv");
  socket_name = socket_name.Append(pipe_name);
  CHECK_LT(socket_name.value().size(), mojo::edk::kMaxSocketNameLength);
  return socket_name;
}

}  // namespace

mojo::edk::NamedPlatformHandle GetServiceProcessChannel() {
  base::FilePath socket_name = GetServiceProcessSocketName();
  VLOG(1) << "ServiceProcessChannel: " << socket_name.value();
  return mojo::edk::NamedPlatformHandle(socket_name.value());
}

bool ForceServiceProcessShutdown(const std::string& /* version */,
                                 base::ProcessId /* process_id */) {
  base::mac::ScopedNSAutoreleasePool pool;
  CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
  CFErrorRef err = NULL;
  bool ret = Launchd::GetInstance()->RemoveJob(label, &err);
  if (!ret) {
    DLOG(ERROR) << "ForceServiceProcessShutdown: " << err << " "
                << base::SysCFStringRefToUTF8(label);
    CFRelease(err);
  }
  return ret;
}

bool GetServiceProcessData(std::string* version, base::ProcessId* pid) {
  base::mac::ScopedNSAutoreleasePool pool;
  CFStringRef label = base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
  base::scoped_nsobject<NSDictionary> launchd_conf(
      base::mac::CFToNSCast(Launchd::GetInstance()->CopyJobDictionary(label)));
  if (!launchd_conf.get()) {
    return false;
  }
  // Anything past here will return true in that there does appear
  // to be a service process of some sort registered with launchd.
  if (version) {
    *version = "0";
    NSString* exe_path = [launchd_conf objectForKey:@ LAUNCH_JOBKEY_PROGRAM];
    if (exe_path) {
      NSString* bundle_path = [[[exe_path stringByDeletingLastPathComponent]
                                stringByDeletingLastPathComponent]
                               stringByDeletingLastPathComponent];
      NSBundle* bundle = [NSBundle bundleWithPath:bundle_path];
      if (bundle) {
        NSString* ns_version =
            [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
        if (ns_version) {
          *version = base::SysNSStringToUTF8(ns_version);
        } else {
          DLOG(ERROR) << "Unable to get version at: "
                      << reinterpret_cast<CFStringRef>(bundle_path);
        }
      } else {
        // The bundle has been deleted out from underneath the registered
        // job.
        DLOG(ERROR) << "Unable to get bundle at: "
                    << reinterpret_cast<CFStringRef>(bundle_path);
      }
    } else {
      DLOG(ERROR) << "Unable to get executable path for service process";
    }
  }
  if (pid) {
    *pid = -1;
    NSNumber* ns_pid = [launchd_conf objectForKey:@ LAUNCH_JOBKEY_PID];
    if (ns_pid) {
     *pid = [ns_pid intValue];
    }
  }
  return true;
}

bool ServiceProcessState::Initialize() {
  CFErrorRef err = NULL;
  CFDictionaryRef dict =
      Launchd::GetInstance()->CopyDictionaryByCheckingIn(&err);
  if (!dict) {
    DLOG(ERROR) << "ServiceProcess must be launched by launchd. "
                << "CopyLaunchdDictionaryByCheckingIn: " << err;
    CFRelease(err);
    return false;
  }
  state_->launchd_conf.reset(dict);
  return true;
}

mojo::edk::ScopedPlatformHandle
ServiceProcessState::GetServiceProcessChannel() {
  DCHECK(state_);
  NSDictionary* ns_launchd_conf = base::mac::CFToNSCast(state_->launchd_conf);
  NSDictionary* socket_dict =
      [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_SOCKETS];
  NSArray* sockets =
      [socket_dict objectForKey:GetServiceProcessLaunchDSocketKey()];
  DCHECK_EQ([sockets count], 1U);
  int socket = [[sockets objectAtIndex:0] intValue];
  return mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(socket));
}

bool CheckServiceProcessReady() {
  std::string version;
  pid_t pid;
  if (!GetServiceProcessData(&version, &pid)) {
    return false;
  }
  base::Version service_version(version);
  bool ready = true;
  if (!service_version.IsValid()) {
    ready = false;
  } else {
    base::Version running_version(version_info::GetVersionNumber());
    if (!running_version.IsValid()) {
      // Our own version is invalid. This is an error case. Pretend that we
      // are out of date.
      NOTREACHED();
      ready = true;
    } else if (running_version.CompareTo(service_version) > 0) {
      ready = false;
    } else {
      ready = true;
    }
  }
  if (!ready) {
    ForceServiceProcessShutdown(version, pid);
  }
  return ready;
}

CFDictionaryRef CreateServiceProcessLaunchdPlist(base::CommandLine* cmd_line,
                                                 bool for_auto_launch) {
  base::mac::ScopedNSAutoreleasePool pool;

  NSString* program =
      base::SysUTF8ToNSString(cmd_line->GetProgram().value());

  std::vector<std::string> args = cmd_line->argv();
  NSMutableArray* ns_args = [NSMutableArray arrayWithCapacity:args.size()];

  for (std::vector<std::string>::iterator iter = args.begin();
       iter < args.end();
       ++iter) {
    [ns_args addObject:base::SysUTF8ToNSString(*iter)];
  }

  NSString* socket_name =
      base::SysUTF8ToNSString(GetServiceProcessSocketName().value());

  NSDictionary* socket =
      [NSDictionary dictionaryWithObject:socket_name
                                  forKey:@LAUNCH_JOBSOCKETKEY_PATHNAME];
  NSDictionary* sockets =
      [NSDictionary dictionaryWithObject:socket
                                  forKey:GetServiceProcessLaunchDSocketKey()];

  // See the man page for launchd.plist.
  NSMutableDictionary* launchd_plist =
      [[NSMutableDictionary alloc] initWithObjectsAndKeys:
        GetServiceProcessLaunchDLabel(), @LAUNCH_JOBKEY_LABEL,
        program, @LAUNCH_JOBKEY_PROGRAM,
        ns_args, @LAUNCH_JOBKEY_PROGRAMARGUMENTS,
        sockets, @LAUNCH_JOBKEY_SOCKETS,
        nil];

  if (for_auto_launch) {
    // We want the service process to be able to exit if there are no services
    // enabled. With a value of NO in the SuccessfulExit key, launchd will
    // relaunch the service automatically in any other case than exiting
    // cleanly with a 0 return code.
    NSDictionary* keep_alive =
        [NSDictionary
           dictionaryWithObject:[NSNumber numberWithBool:NO]
                         forKey:@LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT];
    NSDictionary* auto_launchd_plist =
        [[NSDictionary alloc] initWithObjectsAndKeys:
          [NSNumber numberWithBool:YES], @LAUNCH_JOBKEY_RUNATLOAD,
          keep_alive, @LAUNCH_JOBKEY_KEEPALIVE,
          @kServiceProcessSessionType, @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE,
          nil];
    [launchd_plist addEntriesFromDictionary:auto_launchd_plist];
  }
  return reinterpret_cast<CFDictionaryRef>(launchd_plist);
}

// Writes the launchd property list into the user's LaunchAgents directory,
// creating that directory if needed. This will cause the service process to be
// auto launched on the next user login.
bool ServiceProcessState::AddToAutoRun() {
  // We're creating directories and writing a file.
  base::ThreadRestrictions::AssertIOAllowed();
  DCHECK(autorun_command_line_.get());
  base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
  base::ScopedCFTypeRef<CFDictionaryRef> plist(
      CreateServiceProcessLaunchdPlist(autorun_command_line_.get(), true));
  return Launchd::GetInstance()->WritePlistToFile(Launchd::User,
                                                  Launchd::Agent,
                                                  name,
                                                  plist);
}

bool ServiceProcessState::RemoveFromAutoRun() {
  return RemoveFromLaunchd();
}

bool ServiceProcessState::StateData::WatchExecutable() {
  base::mac::ScopedNSAutoreleasePool pool;
  NSDictionary* ns_launchd_conf = base::mac::CFToNSCast(launchd_conf);
  NSString* exe_path = [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_PROGRAM];
  if (!exe_path) {
    DLOG(ERROR) << "No " LAUNCH_JOBKEY_PROGRAM;
    return false;
  }

  base::FilePath executable_path =
      base::FilePath([exe_path fileSystemRepresentation]);
  std::unique_ptr<ExecFilePathWatcherCallback> callback(
      new ExecFilePathWatcherCallback);
  if (!callback->Init(executable_path)) {
    DLOG(ERROR) << "executable_watcher.Init " << executable_path.value();
    return false;
  }
  if (!executable_watcher.Watch(
          executable_path,
          false,
          base::Bind(&ExecFilePathWatcherCallback::NotifyPathChanged,
                     base::Owned(callback.release())))) {
    DLOG(ERROR) << "executable_watcher.watch " << executable_path.value();
    return false;
  }
  return true;
}

bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) {
  NSString* path_string = base::mac::FilePathToNSString(path);
  NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
  executable_fsref_.reset([[path_url fileReferenceURL] retain]);
  return executable_fsref_.get() != nil;
}

void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path,
                                                    bool error) {
  if (error) {
    NOTREACHED();  // TODO(darin): Do something smarter?
    return;
  }

  base::mac::ScopedNSAutoreleasePool pool;
  bool needs_shutdown = false;
  bool needs_restart = false;
  bool good_bundle = false;

  // Go from bundle/Contents/MacOS/executable to bundle.
  NSURL* bundle_url = [[[executable_fsref_ URLByDeletingLastPathComponent]
      URLByDeletingLastPathComponent] URLByDeletingLastPathComponent];
  if (bundle_url) {
    base::ScopedCFTypeRef<CFBundleRef> bundle(
        CFBundleCreate(kCFAllocatorDefault, base::mac::NSToCFCast(bundle_url)));
    good_bundle = CFBundleGetIdentifier(bundle) != NULL;
  }

  if (!good_bundle) {
    needs_shutdown = true;
  } else {
    bool in_trash = false;
    NSFileManager* file_manager = [NSFileManager defaultManager];
    // Apple deprecated FSDetermineIfRefIsEnclosedByFolder() when deploying to
    // 10.8, but didn't add getRelationship:... until 10.10.  So fall back to
    // the deprecated function while running on 10.9 (and delete the else block
    // when Chromium requires OS X 10.10+).
    if ([file_manager respondsToSelector:@selector(getRelationship:
                                                       ofDirectory:
                                                          inDomain:
                                                       toItemAtURL:
                                                             error:)]) {
      NSURLRelationship relationship;
      if ([file_manager getRelationship:&relationship
                            ofDirectory:NSTrashDirectory
                               inDomain:0
                            toItemAtURL:executable_fsref_
                                  error:nil]) {
        in_trash = relationship == NSURLRelationshipContains;
      }
    } else {
      DCHECK(base::mac::IsAtMostOS10_9());
      Boolean fs_in_trash;
      FSRef ref;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
      if (CFURLGetFSRef(base::mac::NSToCFCast(executable_fsref_.get()), &ref)) {
        // This is ok because it only happens on 10.9 and won't be needed once
        // we stop supporting that.
        OSErr err = FSDetermineIfRefIsEnclosedByFolder(
            kOnAppropriateDisk, kTrashFolderType, &ref, &fs_in_trash);
#pragma clang diagnostic pop
        if (err == noErr && fs_in_trash)
          in_trash = true;
      }
    }
    if (in_trash) {
      needs_shutdown = true;
    } else {
      bool was_moved = true;
      NSString* path_string = base::mac::FilePathToNSString(path);
      NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
      NSURL* path_ref = [path_url fileReferenceURL];
      if (path_ref != nil) {
        if ([path_ref isEqual:executable_fsref_]) {
          was_moved = false;
        }
      }
      if (was_moved) {
        needs_restart = true;
      }
    }
  }
  if (needs_shutdown || needs_restart) {
    // First deal with the plist.
    base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
    if (needs_restart) {
      base::ScopedCFTypeRef<CFMutableDictionaryRef> plist(
          Launchd::GetInstance()->CreatePlistFromFile(
              Launchd::User, Launchd::Agent, name));
      if (plist.get()) {
        NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist);
        NSURL* new_path = [executable_fsref_ filePathURL];
        DCHECK([new_path isFileURL]);
        NSString* ns_new_path = [new_path path];
        [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM];
        base::scoped_nsobject<NSMutableArray> args([[ns_plist
            objectForKey:@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]);
        [args replaceObjectAtIndex:0 withObject:ns_new_path];
        [ns_plist setObject:args forKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS];
        if (!Launchd::GetInstance()->WritePlistToFile(Launchd::User,
                                                      Launchd::Agent,
                                                      name,
                                                      plist)) {
          DLOG(ERROR) << "Unable to rewrite plist.";
          needs_shutdown = true;
        }
      } else {
        DLOG(ERROR) << "Unable to read plist.";
        needs_shutdown = true;
      }
    }
    if (needs_shutdown) {
      if (!RemoveFromLaunchd()) {
        DLOG(ERROR) << "Unable to RemoveFromLaunchd.";
      }
    }

    // Then deal with the process.
    CFStringRef session_type = CFSTR(kServiceProcessSessionType);
    if (needs_restart) {
      if (!Launchd::GetInstance()->RestartJob(Launchd::User,
                                              Launchd::Agent,
                                              name,
                                              session_type)) {
        DLOG(ERROR) << "RestartLaunchdJob";
        needs_shutdown = true;
      }
    }
    if (needs_shutdown) {
      CFStringRef label =
          base::mac::NSToCFCast(GetServiceProcessLaunchDLabel());
      CFErrorRef err = NULL;
      if (!Launchd::GetInstance()->RemoveJob(label, &err)) {
        base::ScopedCFTypeRef<CFErrorRef> scoped_err(err);
        DLOG(ERROR) << "RemoveJob " << err;
        // Exiting with zero, so launchd doesn't restart the process.
        exit(0);
      }
    }
  }
}
