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

#include "chrome/browser/platform_util.h"

#import <Cocoa/Cocoa.h>

#include "base/apple/foundation_util.h"
#include "base/apple/osstatus_logging.h"
#include "base/command_line.h"
#include "base/debug/crash_logging.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/platform_util_internal.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "net/base/apple/url_conversions.h"
#include "ui/views/widget/widget.h"
#include "url/gurl.h"

namespace platform_util {

// Returns true if revealing file paths in the Finder should be skipped
// because it's not needed while running a test.
bool WorkspacePathRevealDisabledForTest() {
  // Note: the kTestType switch is only added on browser tests, but not unit
  // tests. Unit tests need to add the switch manually:
  //
  //   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  //   command_line->AppendSwitch(switches::kTestType);
  //
  return base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType);
}

void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
  DCHECK([NSThread isMainThread]);
  NSURL* url = base::apple::FilePathToNSURL(full_path);

  // The Finder creates a new window on each `full_path` reveal. Skip
  // revealing the path during testing to avoid an avalanche of new
  // Finder windows.
  if (WorkspacePathRevealDisabledForTest()) {
    return;
  }

  [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[ url ]];
}

void OpenFileOnMainThread(const base::FilePath& full_path) {
  DCHECK([NSThread isMainThread]);
  NSURL* url = base::apple::FilePathToNSURL(full_path);
  if (!url)
    return;

  [[NSWorkspace sharedWorkspace]
                openURL:url
          configuration:[NSWorkspaceOpenConfiguration configuration]
      completionHandler:nil];
}

namespace internal {

void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) {
  switch (type) {
    case OPEN_FILE:
      content::GetUIThreadTaskRunner({})->PostTask(
          FROM_HERE, base::BindOnce(&OpenFileOnMainThread, path));
      return;
    case OPEN_FOLDER:
      NSURL* url = base::apple::FilePathToNSURL(path);
      if (!url)
        return;

      // Note that there exists a TOCTOU race between the time that |path| was
      // verified as being a directory and when NSWorkspace invokes Finder (or
      // alternative) to open |path_string|.
      [[NSWorkspace sharedWorkspace] openURL:url];
      return;
  }
}

}  // namespace internal

void OpenExternal(const GURL& url) {
  DCHECK([NSThread isMainThread]);
  NSURL* ns_url = net::NSURLWithGURL(url);

  // https://crbug.com/1504165
  static auto* const crash_key_string = base::debug::AllocateCrashKeyString(
      "platform_util_OpenExternal", base::debug::CrashKeySize::Size64);
  NSUInteger length = [ns_url absoluteString].length;
  NSString* lengthString = [NSString stringWithFormat:@"%lu", length];
  base::debug::ScopedCrashKeyString crash_key(
      crash_key_string, base::SysNSStringToUTF8(lengthString));

  if (!ns_url || ![[NSWorkspace sharedWorkspace] openURL:ns_url]) {
    LOG(WARNING) << "NSWorkspace failed to open URL " << url;
  }
}

gfx::NativeWindow GetTopLevel(gfx::NativeView view) {
  return gfx::NativeWindow([view.GetNativeNSView() window]);
}

gfx::NativeView GetViewForWindow(gfx::NativeWindow native_window) {
  NSWindow* window = native_window.GetNativeNSWindow();
  DCHECK(window);
  DCHECK([window contentView]);
  return gfx::NativeView([window contentView]);
}

gfx::NativeView GetParent(gfx::NativeView view) {
  return gfx::NativeView(nil);
}

bool IsWindowActive(gfx::NativeWindow native_window) {
  // If |window| is a doppelganger NSWindow being used to track an NSWindow that
  // is being hosted in another process, then use the views::Widget interface to
  // interact with it.
  views::Widget* widget =
      views::Widget::GetWidgetForNativeWindow(native_window);
  if (widget)
    return widget->IsActive();

  NSWindow* window = native_window.GetNativeNSWindow();
  return [window isKeyWindow] || [window isMainWindow];
}

void ActivateWindow(gfx::NativeWindow native_window) {
  views::Widget* widget =
      views::Widget::GetWidgetForNativeWindow(native_window);
  if (widget)
    return widget->Activate();

  NSWindow* window = native_window.GetNativeNSWindow();
  [window makeKeyAndOrderFront:nil];
}

bool IsVisible(gfx::NativeView native_view) {
  views::Widget* widget = views::Widget::GetWidgetForNativeView(native_view);
  if (widget)
    return widget->IsVisible();

  // A reasonable approximation of how you'd expect this to behave.
  NSView* view = native_view.GetNativeNSView();
  return (view &&
          ![view isHiddenOrHasHiddenAncestor] &&
          [view window] &&
          [[view window] isVisible]);
}

bool IsSwipeTrackingFromScrollEventsEnabled() {
  return NSEvent.swipeTrackingFromScrollEventsEnabled;
}

NSWindow* GetActiveWindow() {
  return [NSApp keyWindow];
}

}  // namespace platform_util
