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

// On Mac, one can't make shortcuts with command-line arguments. Instead, we
// produce small app bundles which locate the Chromium framework and load it,
// passing the appropriate data. This is the entry point into the framework for
// those app bundles.

#import <Cocoa/Cocoa.h>
#include <vector>

#include "apps/app_shim/app_shim_messages.h"
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/launch_services_util.h"
#include "base/mac/mac_logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/mac/app_mode_common.h"
#include "grit/generated_resources.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

// Timeout in seconds to wait for a reply for the initial Apple Event. Note that
// kAEDefaultTimeout on Mac is "about one minute" according to Apple's
// documentation, but is no longer supported for asynchronous Apple Events.
const int kPingChromeTimeoutSeconds = 60;

const app_mode::ChromeAppModeInfo* g_info;
base::Thread* g_io_thread = NULL;

}  // namespace

class AppShimController;

// An application delegate to catch user interactions and send the appropriate
// IPC messages to Chrome.
@interface AppShimDelegate : NSObject<NSApplicationDelegate> {
 @private
  AppShimController* appShimController_;  // Weak, initially NULL.
  BOOL terminateNow_;
  BOOL terminateRequested_;
  std::vector<base::FilePath> filesToOpenAtStartup_;
}

// The controller is initially NULL. Setting it indicates to the delegate that
// the controller has finished initialization.
- (void)setController:(AppShimController*)controller;

// Gets files that were queued because the controller was not ready.
// Returns whether any FilePaths were added to |out|.
- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out;

// If the controller is ready, this sends a FocusApp with the files to open.
// Otherwise, this adds the files to |filesToOpenAtStartup_|.
// Takes an array of NSString*.
- (void)openFiles:(NSArray*)filename;

// Terminate immediately. This is necessary as we override terminate: to send
// a QuitApp message.
- (void)terminateNow;

@end

// The AppShimController is responsible for communication with the main Chrome
// process, and generally controls the lifetime of the app shim process.
class AppShimController : public IPC::Listener {
 public:
  AppShimController();
  virtual ~AppShimController();

  // Called when the main Chrome process responds to the Apple Event ping that
  // was sent, or when the ping fails (if |success| is false).
  void OnPingChromeReply(bool success);

  // Called |kPingChromeTimeoutSeconds| after startup, to allow a timeout on the
  // ping event to be detected.
  void OnPingChromeTimeout();

  // Connects to Chrome and sends a LaunchApp message.
  void Init();

  // Create a channel from |socket_path| and send a LaunchApp message.
  void CreateChannelAndSendLaunchApp(const base::FilePath& socket_path);

  // Builds main menu bar items.
  void SetUpMenu();

  void SendSetAppHidden(bool hidden);

  void SendQuitApp();

  // Called when the app is activated, e.g. by clicking on it in the dock, by
  // dropping a file on the dock icon, or by Cmd+Tabbing to it.
  // Returns whether the message was sent.
  bool SendFocusApp(apps::AppShimFocusType focus_type,
                    const std::vector<base::FilePath>& files);

 private:
  // IPC::Listener implemetation.
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
  virtual void OnChannelError() OVERRIDE;

  // If Chrome failed to launch the app, |success| will be false and the app
  // shim process should die.
  void OnLaunchAppDone(apps::AppShimLaunchResult result);

  // Hide this app.
  void OnHide();

  // Requests user attention.
  void OnRequestUserAttention();

  // Terminates the app shim process.
  void Close();

  base::FilePath user_data_dir_;
  scoped_ptr<IPC::ChannelProxy> channel_;
  base::scoped_nsobject<AppShimDelegate> delegate_;
  bool launch_app_done_;
  bool ping_chrome_reply_received_;

  DISALLOW_COPY_AND_ASSIGN(AppShimController);
};

AppShimController::AppShimController()
    : delegate_([[AppShimDelegate alloc] init]),
      launch_app_done_(false),
      ping_chrome_reply_received_(false) {
  // Since AppShimController is created before the main message loop starts,
  // NSApp will not be set, so use sharedApplication.
  [[NSApplication sharedApplication] setDelegate:delegate_];
}

AppShimController::~AppShimController() {
  // Un-set the delegate since NSApplication does not retain it.
  [[NSApplication sharedApplication] setDelegate:nil];
}

void AppShimController::OnPingChromeReply(bool success) {
  ping_chrome_reply_received_ = true;
  if (!success) {
    [NSApp terminate:nil];
    return;
  }

  Init();
}

void AppShimController::OnPingChromeTimeout() {
  if (!ping_chrome_reply_received_)
    [NSApp terminate:nil];
}

void AppShimController::Init() {
  DCHECK(g_io_thread);

  SetUpMenu();

  // Chrome will relaunch shims when relaunching apps.
  if (base::mac::IsOSLionOrLater())
    [NSApp disableRelaunchOnLogin];

  // The user_data_dir for shims actually contains the app_data_path.
  // I.e. <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/
  user_data_dir_ = g_info->user_data_dir.DirName().DirName().DirName();
  CHECK(!user_data_dir_.empty());

  base::FilePath symlink_path =
      user_data_dir_.Append(app_mode::kAppShimSocketSymlinkName);

  base::FilePath socket_path;
  if (!base::ReadSymbolicLink(symlink_path, &socket_path)) {
    // The path in the user data dir is not a symlink, try connecting directly.
    CreateChannelAndSendLaunchApp(symlink_path);
    return;
  }

  app_mode::VerifySocketPermissions(socket_path);

  CreateChannelAndSendLaunchApp(socket_path);
}

void AppShimController::CreateChannelAndSendLaunchApp(
    const base::FilePath& socket_path) {
  IPC::ChannelHandle handle(socket_path.value());
  channel_ = IPC::ChannelProxy::Create(handle,
                                       IPC::Channel::MODE_NAMED_CLIENT,
                                       this,
                                       g_io_thread->message_loop_proxy().get());

  bool launched_by_chrome =
      CommandLine::ForCurrentProcess()->HasSwitch(
          app_mode::kLaunchedByChromeProcessId);
  apps::AppShimLaunchType launch_type = launched_by_chrome ?
          apps::APP_SHIM_LAUNCH_REGISTER_ONLY : apps::APP_SHIM_LAUNCH_NORMAL;

  [delegate_ setController:this];

  std::vector<base::FilePath> files;
  [delegate_ getFilesToOpenAtStartup:&files];

  channel_->Send(new AppShimHostMsg_LaunchApp(
      g_info->profile_dir, g_info->app_mode_id, launch_type, files));
}

void AppShimController::SetUpMenu() {
  NSString* title = base::SysUTF16ToNSString(g_info->app_mode_name);

  // Create a main menu since [NSApp mainMenu] is nil.
  base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:title]);

  // The title of the first item is replaced by OSX with the name of the app and
  // bold styling. Create a dummy item for this and make it hidden.
  NSMenuItem* dummy_item = [main_menu addItemWithTitle:title
                                                action:nil
                                         keyEquivalent:@""];
  base::scoped_nsobject<NSMenu> dummy_submenu(
      [[NSMenu alloc] initWithTitle:title]);
  [dummy_item setSubmenu:dummy_submenu];
  [dummy_item setHidden:YES];

  // Construct an unbolded app menu, to match how it appears in the Chrome menu
  // bar when the app is focused.
  NSMenuItem* item = [main_menu addItemWithTitle:title
                                          action:nil
                                   keyEquivalent:@""];
  base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:title]);
  [item setSubmenu:submenu];

  // Add a quit entry.
  NSString* quit_localized_string =
      l10n_util::GetNSStringF(IDS_EXIT_MAC, g_info->app_mode_name);
  [submenu addItemWithTitle:quit_localized_string
                     action:@selector(terminate:)
              keyEquivalent:@"q"];

  // Add File, Edit, and Window menus. These are just here to make the
  // transition smoother, i.e. from another application to the shim then to
  // Chrome.
  [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_FILE_MENU_MAC)
                       action:nil
                keyEquivalent:@""];
  [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_EDIT_MENU_MAC)
                       action:nil
                keyEquivalent:@""];
  [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_WINDOW_MENU_MAC)
                       action:nil
                keyEquivalent:@""];

  [NSApp setMainMenu:main_menu];
}

void AppShimController::SendQuitApp() {
  channel_->Send(new AppShimHostMsg_QuitApp);
}

bool AppShimController::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(AppShimController, message)
    IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone)
    IPC_MESSAGE_HANDLER(AppShimMsg_Hide, OnHide)
    IPC_MESSAGE_HANDLER(AppShimMsg_RequestUserAttention, OnRequestUserAttention)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void AppShimController::OnChannelError() {
  Close();
}

void AppShimController::OnLaunchAppDone(apps::AppShimLaunchResult result) {
  if (result != apps::APP_SHIM_LAUNCH_SUCCESS) {
    Close();
    return;
  }

  std::vector<base::FilePath> files;
  if ([delegate_ getFilesToOpenAtStartup:&files])
    SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES, files);

  launch_app_done_ = true;
}

void AppShimController::OnHide() {
  [NSApp hide:nil];
}

void AppShimController::OnRequestUserAttention() {
  [NSApp requestUserAttention:NSInformationalRequest];
}

void AppShimController::Close() {
  [delegate_ terminateNow];
}

bool AppShimController::SendFocusApp(apps::AppShimFocusType focus_type,
                                     const std::vector<base::FilePath>& files) {
  if (launch_app_done_) {
    channel_->Send(new AppShimHostMsg_FocusApp(focus_type, files));
    return true;
  }

  return false;
}

void AppShimController::SendSetAppHidden(bool hidden) {
  channel_->Send(new AppShimHostMsg_SetAppHidden(hidden));
}

@implementation AppShimDelegate

- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out {
  if (filesToOpenAtStartup_.empty())
    return NO;

  out->insert(out->end(),
              filesToOpenAtStartup_.begin(),
              filesToOpenAtStartup_.end());
  filesToOpenAtStartup_.clear();
  return YES;
}

- (void)setController:(AppShimController*)controller {
  appShimController_ = controller;
}

- (void)openFiles:(NSArray*)filenames {
  std::vector<base::FilePath> filePaths;
  for (NSString* filename in filenames)
    filePaths.push_back(base::mac::NSStringToFilePath(filename));

  // If the AppShimController is ready, try to send a FocusApp. If that fails,
  // (e.g. if launching has not finished), enqueue the files.
  if (appShimController_ &&
      appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES,
                                       filePaths)) {
    return;
  }

  filesToOpenAtStartup_.insert(filesToOpenAtStartup_.end(),
                               filePaths.begin(),
                               filePaths.end());
}

- (BOOL)application:(NSApplication*)app
           openFile:(NSString*)filename {
  [self openFiles:@[filename]];
  return YES;
}

- (void)application:(NSApplication*)app
          openFiles:(NSArray*)filenames {
  [self openFiles:filenames];
  [app replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}

- (BOOL)applicationOpenUntitledFile:(NSApplication*)app {
  if (appShimController_) {
    return appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_REOPEN,
                                            std::vector<base::FilePath>());
  }

  return NO;
}

- (void)applicationWillBecomeActive:(NSNotification*)notification {
  if (appShimController_) {
    appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_NORMAL,
                                     std::vector<base::FilePath>());
  }
}

- (NSApplicationTerminateReply)
    applicationShouldTerminate:(NSApplication*)sender {
  if (terminateNow_ || !appShimController_)
    return NSTerminateNow;

  appShimController_->SendQuitApp();
  // Wait for the channel to close before terminating.
  terminateRequested_ = YES;
  return NSTerminateLater;
}

- (void)applicationWillHide:(NSNotification*)notification {
  if (appShimController_)
    appShimController_->SendSetAppHidden(true);
}

- (void)applicationWillUnhide:(NSNotification*)notification {
  if (appShimController_)
    appShimController_->SendSetAppHidden(false);
}

- (void)terminateNow {
  if (terminateRequested_) {
    [NSApp replyToApplicationShouldTerminate:NSTerminateNow];
    return;
  }

  terminateNow_ = YES;
  [NSApp terminate:nil];
}

@end

//-----------------------------------------------------------------------------

// A ReplyEventHandler is a helper class to send an Apple Event to a process
// and call a callback when the reply returns.
//
// This is used to 'ping' the main Chrome process -- once Chrome has sent back
// an Apple Event reply, it's guaranteed that it has opened the IPC channel
// that the app shim will connect to.
@interface ReplyEventHandler : NSObject {
  base::Callback<void(bool)> onReply_;
  AEDesc replyEvent_;
}
// Sends an Apple Event to the process identified by |psn|, and calls |replyFn|
// when the reply is received. Internally this creates a ReplyEventHandler,
// which will delete itself once the reply event has been received.
+ (void)pingProcess:(const ProcessSerialNumber&)psn
            andCall:(base::Callback<void(bool)>)replyFn;
@end

@interface ReplyEventHandler (PrivateMethods)
// Initialise the reply event handler. Doesn't register any handlers until
// |-pingProcess:| is called. |replyFn| is the function to be called when the
// Apple Event reply arrives.
- (id)initWithCallback:(base::Callback<void(bool)>)replyFn;

// Sends an Apple Event ping to the process identified by |psn| and registers
// to listen for a reply.
- (void)pingProcess:(const ProcessSerialNumber&)psn;

// Called when a response is received from the target process for the ping sent
// by |-pingProcess:|.
- (void)message:(NSAppleEventDescriptor*)event
      withReply:(NSAppleEventDescriptor*)reply;

// Calls |onReply_|, passing it |success| to specify whether the ping was
// successful.
- (void)closeWithSuccess:(bool)success;
@end

@implementation ReplyEventHandler
+ (void)pingProcess:(const ProcessSerialNumber&)psn
            andCall:(base::Callback<void(bool)>)replyFn {
  // The object will release itself when the reply arrives, or possibly earlier
  // if an unrecoverable error occurs.
  ReplyEventHandler* handler =
      [[ReplyEventHandler alloc] initWithCallback:replyFn];
  [handler pingProcess:psn];
}
@end

@implementation ReplyEventHandler (PrivateMethods)
- (id)initWithCallback:(base::Callback<void(bool)>)replyFn {
  if ((self = [super init])) {
    onReply_ = replyFn;
  }
  return self;
}

- (void)pingProcess:(const ProcessSerialNumber&)psn {
  // Register the reply listener.
  NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
  [em setEventHandler:self
          andSelector:@selector(message:withReply:)
        forEventClass:'aevt'
           andEventID:'ansr'];
  // Craft the Apple Event to send.
  NSAppleEventDescriptor* target = [NSAppleEventDescriptor
      descriptorWithDescriptorType:typeProcessSerialNumber
                             bytes:&psn
                            length:sizeof(psn)];
  NSAppleEventDescriptor* initial_event =
      [NSAppleEventDescriptor
          appleEventWithEventClass:app_mode::kAEChromeAppClass
                           eventID:app_mode::kAEChromeAppPing
                  targetDescriptor:target
                          returnID:kAutoGenerateReturnID
                     transactionID:kAnyTransactionID];

  // Note that AESendMessage effectively ignores kAEDefaultTimeout, because this
  // call does not pass kAEWantReceipt (which is deprecated and unsupported on
  // Mac). Instead, rely on OnPingChromeTimeout().
  OSStatus status = AESendMessage(
      [initial_event aeDesc], &replyEvent_, kAEQueueReply, kAEDefaultTimeout);
  if (status != noErr) {
    OSSTATUS_LOG(ERROR, status) << "AESendMessage";
    [self closeWithSuccess:false];
  }
}

- (void)message:(NSAppleEventDescriptor*)event
      withReply:(NSAppleEventDescriptor*)reply {
  [self closeWithSuccess:true];
}

- (void)closeWithSuccess:(bool)success {
  onReply_.Run(success);
  NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
  [em removeEventHandlerForEventClass:'aevt' andEventID:'ansr'];
  [self release];
}
@end

//-----------------------------------------------------------------------------

extern "C" {

// |ChromeAppModeStart()| is the point of entry into the framework from the app
// mode loader.
__attribute__((visibility("default")))
int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info);

}  // extern "C"

int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) {
  CommandLine::Init(info->argc, info->argv);

  base::mac::ScopedNSAutoreleasePool scoped_pool;
  base::AtExitManager exit_manager;
  chrome::RegisterPathProvider();

  if (info->major_version < app_mode::kCurrentChromeAppModeInfoMajorVersion) {
    RAW_LOG(ERROR, "App Mode Loader too old.");
    return 1;
  }
  if (info->major_version > app_mode::kCurrentChromeAppModeInfoMajorVersion) {
    RAW_LOG(ERROR, "Browser Framework too old to load App Shortcut.");
    return 1;
  }

  g_info = info;

  // Set bundle paths. This loads the bundles.
  base::mac::SetOverrideOuterBundlePath(g_info->chrome_outer_bundle_path);
  base::mac::SetOverrideFrameworkBundlePath(
      g_info->chrome_versioned_path.Append(chrome::kFrameworkName));

  // Calculate the preferred locale used by Chrome.
  // We can't use l10n_util::OverrideLocaleWithCocoaLocale() because it calls
  // [base::mac::OuterBundle() preferredLocalizations] which gets localizations
  // from the bundle of the running app (i.e. it is equivalent to
  // [[NSBundle mainBundle] preferredLocalizations]) instead of the target
  // bundle.
  NSArray* preferred_languages = [NSLocale preferredLanguages];
  NSArray* supported_languages = [base::mac::OuterBundle() localizations];
  std::string preferred_localization;
  for (NSString* language in preferred_languages) {
    if ([supported_languages containsObject:language]) {
      preferred_localization = base::SysNSStringToUTF8(language);
      break;
    }
  }
  std::string locale = l10n_util::NormalizeLocale(
      l10n_util::GetApplicationLocale(preferred_localization));

  // Load localized strings.
  ResourceBundle::InitSharedInstanceLocaleOnly(locale, NULL);

  // Launch the IO thread.
  base::Thread::Options io_thread_options;
  io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
  base::Thread *io_thread = new base::Thread("CrAppShimIO");
  io_thread->StartWithOptions(io_thread_options);
  g_io_thread = io_thread;

  // Find already running instances of Chrome.
  pid_t pid = -1;
  std::string chrome_process_id = CommandLine::ForCurrentProcess()->
      GetSwitchValueASCII(app_mode::kLaunchedByChromeProcessId);
  if (!chrome_process_id.empty()) {
    if (!base::StringToInt(chrome_process_id, &pid))
      LOG(FATAL) << "Invalid PID: " << chrome_process_id;
  } else {
    NSString* chrome_bundle_id = [base::mac::OuterBundle() bundleIdentifier];
    NSArray* existing_chrome = [NSRunningApplication
        runningApplicationsWithBundleIdentifier:chrome_bundle_id];
    if ([existing_chrome count] > 0)
      pid = [[existing_chrome objectAtIndex:0] processIdentifier];
  }

  AppShimController controller;
  base::MessageLoopForUI main_message_loop;
  main_message_loop.set_thread_name("MainThread");
  base::PlatformThread::SetName("CrAppShimMain");

  // In tests, launching Chrome does nothing, and we won't get a ping response,
  // so just assume the socket exists.
  if (pid == -1 &&
      !CommandLine::ForCurrentProcess()->HasSwitch(
          app_mode::kLaunchedForTest)) {
    // Launch Chrome if it isn't already running.
    ProcessSerialNumber psn;
    CommandLine command_line(CommandLine::NO_PROGRAM);
    command_line.AppendSwitch(switches::kSilentLaunch);

    // If the shim is the app launcher, pass --show-app-list when starting a new
    // Chrome process to inform startup codepaths and load the correct profile.
    if (info->app_mode_id == app_mode::kAppListModeId) {
      command_line.AppendSwitch(switches::kShowAppList);
    } else {
      command_line.AppendSwitchPath(switches::kProfileDirectory,
                                    info->profile_dir);
    }

    bool success =
        base::mac::OpenApplicationWithPath(base::mac::OuterBundlePath(),
                                           command_line,
                                           kLSLaunchDefaults,
                                           &psn);
    if (!success)
      return 1;

    base::Callback<void(bool)> on_ping_chrome_reply =
        base::Bind(&AppShimController::OnPingChromeReply,
                   base::Unretained(&controller));

    // This code abuses the fact that Apple Events sent before the process is
    // fully initialized don't receive a reply until its run loop starts. Once
    // the reply is received, Chrome will have opened its IPC port, guaranteed.
    [ReplyEventHandler pingProcess:psn
                           andCall:on_ping_chrome_reply];

    main_message_loop.PostDelayedTask(
        FROM_HERE,
        base::Bind(&AppShimController::OnPingChromeTimeout,
                   base::Unretained(&controller)),
        base::TimeDelta::FromSeconds(kPingChromeTimeoutSeconds));
  } else {
    // Chrome already running. Proceed to init. This could still fail if Chrome
    // is still starting up or shutting down, but the process will exit quickly,
    // which is preferable to waiting for the Apple Event to timeout after one
    // minute.
    main_message_loop.PostTask(
        FROM_HERE,
        base::Bind(&AppShimController::Init,
                   base::Unretained(&controller)));
  }

  main_message_loop.Run();
  return 0;
}
