// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "base/mac/launch_application.h"

#include "base/command_line.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/types/expected.h"

namespace base::mac {

namespace {

NSArray* CommandLineArgsToArgsArray(const CommandLineArgs& command_line_args) {
  if (const CommandLine* command_line =
          absl::get_if<CommandLine>(&command_line_args)) {
    const auto& argv = command_line->argv();
    size_t argc = argv.size();
    DCHECK_GT(argc, 0lu);

    NSMutableArray* args_array = [NSMutableArray arrayWithCapacity:argc - 1];
    // NSWorkspace automatically adds the binary path as the first argument and
    // thus it should not be included in the list.
    for (size_t i = 1; i < argc; ++i) {
      [args_array addObject:base::SysUTF8ToNSString(argv[i])];
    }

    return args_array;
  }

  if (const std::vector<std::string>* string_vector =
          absl::get_if<std::vector<std::string>>(&command_line_args)) {
    NSMutableArray* args_array =
        [NSMutableArray arrayWithCapacity:string_vector->size()];
    for (const auto& arg : *string_vector) {
      [args_array addObject:base::SysUTF8ToNSString(arg)];
    }
  }

  return @[];
}

NSWorkspaceOpenConfiguration* GetOpenConfiguration(
    LaunchApplicationOptions options,
    const CommandLineArgs& command_line_args) API_AVAILABLE(macos(10.15)) {
  NSWorkspaceOpenConfiguration* config =
      [NSWorkspaceOpenConfiguration configuration];

  config.activates = options.activate;
  config.createsNewApplicationInstance = options.create_new_instance;
  config.promptsUserIfNeeded = options.prompt_user_if_needed;
  config.arguments = CommandLineArgsToArgsArray(command_line_args);

  return config;
}

NSWorkspaceLaunchOptions GetLaunchOptions(LaunchApplicationOptions options) {
  NSWorkspaceLaunchOptions launch_options = NSWorkspaceLaunchDefault;

  if (!options.activate) {
    launch_options |= NSWorkspaceLaunchWithoutActivation;
  }
  if (options.create_new_instance) {
    launch_options |= NSWorkspaceLaunchNewInstance;
  }
  if (options.prompt_user_if_needed) {
    launch_options |= NSWorkspaceLaunchWithErrorPresentation;
  }

  return launch_options;
}

}  // namespace

void LaunchApplication(const base::FilePath& app_bundle_path,
                       const CommandLineArgs& command_line_args,
                       const std::vector<std::string>& url_specs,
                       LaunchApplicationOptions options,
                       LaunchApplicationCallback callback) {
  __block LaunchApplicationCallback callback_block_access = std::move(callback);

  NSURL* bundle_url = FilePathToNSURL(app_bundle_path);
  if (!bundle_url) {
    dispatch_async(dispatch_get_main_queue(), ^{
      std::move(callback_block_access)
          .Run(base::unexpected([NSError errorWithDomain:NSCocoaErrorDomain
                                                    code:NSFileNoSuchFileError
                                                userInfo:nil]));
    });
    return;
  }

  NSMutableArray* ns_urls = nil;
  if (!url_specs.empty()) {
    ns_urls = [NSMutableArray arrayWithCapacity:url_specs.size()];
    for (const auto& url_spec : url_specs) {
      [ns_urls
          addObject:[NSURL URLWithString:base::SysUTF8ToNSString(url_spec)]];
    }
  }

  if (@available(macOS 10.15, *)) {
    void (^action_block)(NSRunningApplication*, NSError*) =
        ^void(NSRunningApplication* app, NSError* error) {
          dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
              LOG(ERROR) << base::SysNSStringToUTF8(error.localizedDescription);
              std::move(callback_block_access).Run(base::unexpected(error));
            } else {
              std::move(callback_block_access).Run(app);
            }
          });
        };

    NSWorkspaceOpenConfiguration* configuration =
        GetOpenConfiguration(options, command_line_args);

    if (ns_urls) {
      [NSWorkspace.sharedWorkspace openURLs:ns_urls
                       withApplicationAtURL:bundle_url
                              configuration:configuration
                          completionHandler:action_block];
    } else {
      [NSWorkspace.sharedWorkspace openApplicationAtURL:bundle_url
                                          configuration:configuration
                                      completionHandler:action_block];
    }
  } else {
    NSDictionary* configuration = @{
      NSWorkspaceLaunchConfigurationArguments :
          CommandLineArgsToArgsArray(command_line_args),
    };

    NSWorkspaceLaunchOptions launch_options = GetLaunchOptions(options);

    NSError* error = nil;
    NSRunningApplication* app;
    if (ns_urls) {
      app = [NSWorkspace.sharedWorkspace openURLs:ns_urls
                             withApplicationAtURL:bundle_url
                                          options:launch_options
                                    configuration:configuration
                                            error:&error];
    } else {
      app = [NSWorkspace.sharedWorkspace launchApplicationAtURL:bundle_url
                                                        options:launch_options
                                                  configuration:configuration
                                                          error:&error];
    }

    dispatch_async(dispatch_get_main_queue(), ^{
      if (error) {
        LOG(ERROR) << base::SysNSStringToUTF8(error.localizedDescription);
        std::move(callback_block_access).Run(base::unexpected(error));
      } else {
        std::move(callback_block_access).Run(app);
      }
    });
  }
}

}  // namespace base::mac
