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

#import "chrome/browser/ui/cocoa/applescript/window_applescript.h"

#include <memory>

#import "base/apple/foundation_util.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "base/strings/sys_string_conversions.h"
#include "base/time/time.h"
#import "chrome/browser/app_controller_mac.h"
#import "chrome/browser/chrome_browser_application_mac.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
#include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
#import "chrome/browser/ui/cocoa/applescript/tab_applescript.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"

@interface WindowAppleScript ()

// The NSWindow that corresponds to this window.
@property(readonly) NSWindow* nativeHandle;

@end

@implementation WindowAppleScript {
  // A note about lifetimes: It's not expected that this object will ever be
  // deleted behind the back of this class. AppleScript does not hold onto
  // objects between script runs; it will retain the object specifier, and if
  // needed again, AppleScript will re-iterate over the objects, and look for
  // the specified object. However, there's no hard guarantee that a race
  // couldn't be made to happen, and in tests things are torn down at odd times,
  // so it's best to use a real weak pointer.
  base::WeakPtr<BrowserWindowInterface> _browser;
}

- (instancetype)init {
  // Check which mode to open a new window.
  NSScriptCommand* command = [NSScriptCommand currentCommand];
  NSString* mode = command.evaluatedArguments[@"KeyDictionary"][@"mode"];

  Profile* lastProfile = AppController.sharedController.lastProfile;
  if (!lastProfile) {
    AppleScript::SetError(AppleScript::Error::kGetProfile);
    return nil;
  } else {
    // Ensure that the profile is a non-OTR profile, so that it's possible to
    // create a non-OTR window, below.
    lastProfile = lastProfile->GetOriginalProfile();
  }

  Profile* profile;
  if ([mode isEqualToString:AppleScript::kIncognitoWindowMode]) {
    profile = lastProfile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
  } else if ([mode isEqualToString:AppleScript::kNormalWindowMode] || !mode) {
    profile = lastProfile;
  } else {
    // Mode cannot be anything else.
    AppleScript::SetError(AppleScript::Error::kInvalidMode);
    return nil;
  }
  // Set the mode to nil, to ensure that it is not set once more.
  [command.evaluatedArguments[@"KeyDictionary"] setValue:nil forKey:@"mode"];
  return [self initWithProfile:profile];
}

- (instancetype)initWithProfile:(Profile*)aProfile {
  if (!aProfile) {
    self = nil;
    return nil;
  }

  if ((self = [super init])) {
    // Since AppleScript requests can arrive at any time, including during
    // browser shutdown or profile deletion, we have to check whether it's okay
    // to spawn a new browser for the specified profile or not.
    if (Browser::GetCreationStatusForProfile(aProfile) !=
        Browser::CreationStatus::kOk) {
      self = nil;
      return nil;
    }

    Browser* browser = Browser::Create(
        Browser::CreateParams(aProfile, /*user_gesture=*/false));
    // TODO(crbug.com/452431839): Make a new NewTabTypes enum value
    // for new tabs made with AppleScript requests.
    chrome::NewTab(browser, NewTabTypes::kNewTabCommand);
    browser->window()->Show();

    _browser = browser->GetWeakPtr();
    self.uniqueID =
        [NSString stringWithFormat:@"%d", _browser->GetSessionID().id()];
  }
  return self;
}

- (instancetype)initWithBrowser:(BrowserWindowInterface*)browser {
  if (!browser) {
    self = nil;
    return nil;
  }

  if ((self = [super init])) {
    // It is safe to be weak, if a window goes away (eg user closing a window)
    // the AppleScript runtime calls appleScriptWindows in
    // BrowserCrApplication and this particular window is never returned.
    _browser = browser->GetWeakPtr();
    self.uniqueID =
        [NSString stringWithFormat:@"%d", _browser->GetSessionID().id()];
  }
  return self;
}

- (NSWindow*)nativeHandle {
  if (!_browser) {
    return nil;
  }

  // GetWindow() can return null during startup.
  if (_browser->GetWindow()) {
    return _browser->GetWindow()->GetNativeWindow().GetNativeNSWindow();
  }
  return nil;
}

- (NSNumber*)activeTabIndex {
  if (!_browser) {
    return nil;
  }

  // Note: AppleScript is 1-based, that is lists begin with index 1.
  int activeTabIndex = _browser->GetTabStripModel()->active_index() + 1;
  if (!activeTabIndex) {
    return nil;
  }
  return @(activeTabIndex);
}

- (void)setActiveTabIndex:(NSNumber*)anActiveTabIndex {
  if (!_browser) {
    return;
  }

  // Note: AppleScript is 1-based, that is lists begin with index 1.
  int atIndex = anActiveTabIndex.intValue - 1;
  if (atIndex >= 0 && atIndex < _browser->GetTabStripModel()->count()) {
    _browser->GetTabStripModel()->ActivateTabAt(
        atIndex, TabStripUserGestureDetails(
                     TabStripUserGestureDetails::GestureType::kOther));
  } else {
    AppleScript::SetError(AppleScript::Error::kInvalidTabIndex);
  }
}

- (NSString*)givenName {
  if (!_browser) {
    return nil;
  }

  return base::SysUTF8ToNSString(
      _browser->GetBrowserForMigrationOnly()->user_title());
}

- (void)setGivenName:(NSString*)name {
  if (!_browser) {
    return;
  }

  _browser->GetBrowserForMigrationOnly()->SetWindowUserTitle(
      base::SysNSStringToUTF8(name));
}

- (NSString*)mode {
  if (!_browser) {
    return nil;
  }

  Profile* profile = _browser->GetProfile();
  if (profile->IsOffTheRecord()) {
    return AppleScript::kIncognitoWindowMode;
  }
  return AppleScript::kNormalWindowMode;
}

- (void)setMode:(NSString*)theMode {
  // Cannot set mode after window is created.
  if (theMode) {
    AppleScript::SetError(AppleScript::Error::kSetMode);
  }
}

- (TabAppleScript*)activeTab {
  if (!_browser) {
    return nil;
  }

  TabAppleScript* currentTab = [[TabAppleScript alloc]
      initWithWebContents:_browser->GetTabStripModel()->GetActiveWebContents()];
  [currentTab setContainer:self property:AppleScript::kTabsProperty];
  return currentTab;
}

- (NSArray<TabAppleScript*>*)tabs {
  if (!_browser) {
    return nil;
  }

  TabStripModel* tabStrip = _browser->GetTabStripModel();
  NSMutableArray* tabs = [NSMutableArray arrayWithCapacity:tabStrip->count()];

  for (int i = 0; i < tabStrip->count(); ++i) {
    // Check to see if tab is closing.
    content::WebContents* webContents = tabStrip->GetWebContentsAt(i);
    if (webContents->IsBeingDestroyed()) {
      continue;
    }

    TabAppleScript* tab =
        [[TabAppleScript alloc] initWithWebContents:webContents];
    [tab setContainer:self property:AppleScript::kTabsProperty];
    [tabs addObject:tab];
  }
  return tabs;
}

- (void)insertInTabs:(TabAppleScript*)aTab {
  if (!_browser) {
    return;
  }

  // This method gets called when a new tab is created so
  // the container and property are set here.
  [aTab setContainer:self property:AppleScript::kTabsProperty];

  // Set how long it takes a tab to be created.
  base::TimeTicks newTabStartTime = base::TimeTicks::Now();
  content::WebContents* contents = chrome::AddSelectedTabWithURL(
      _browser->GetBrowserForMigrationOnly(), GURL(chrome::kChromeUINewTabURL),
      ui::PAGE_TRANSITION_TYPED);
  CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
  core_tab_helper->set_new_tab_start_time(newTabStartTime);
  [aTab setWebContents:contents];
}

- (void)insertInTabs:(TabAppleScript*)aTab atIndex:(int)index {
  if (!_browser) {
    return;
  }

  // This method gets called when a new tab is created so
  // the container and property are set here.
  [aTab setContainer:self property:AppleScript::kTabsProperty];

  // Set how long it takes a tab to be created.
  base::TimeTicks newTabStartTime = base::TimeTicks::Now();
  NavigateParams params(_browser.get(), GURL(chrome::kChromeUINewTabURL),
                        ui::PAGE_TRANSITION_TYPED);
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  params.tabstrip_index = index;
  Navigate(&params);
  CoreTabHelper* core_tab_helper =
      CoreTabHelper::FromWebContents(params.navigated_or_inserted_contents);
  core_tab_helper->set_new_tab_start_time(newTabStartTime);

  [aTab setWebContents:params.navigated_or_inserted_contents];
}

- (void)removeFromTabsAtIndex:(int)index {
  if (!_browser) {
    return;
  }

  if (index < 0 || index >= _browser->GetTabStripModel()->count()) {
    return;
  }
  _browser->GetTabStripModel()->CloseWebContentsAt(
      index, TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB);
}

- (NSNumber*)orderedIndex {
  return @(self.nativeHandle.orderedIndex);
}

- (void)setOrderedIndex:(NSNumber*)anIndex {
  int index = anIndex.intValue - 1;
  if (index < 0 || index >= static_cast<int>(chrome::GetTotalBrowserCount())) {
    AppleScript::SetError(AppleScript::Error::kWrongIndex);
    return;
  }
  self.nativeHandle.orderedIndex = index;
}

// Get and set values from the associated NSWindow.
- (id)valueForUndefinedKey:(NSString*)key {
  return [self.nativeHandle valueForKey:key];
}

- (void)setValue:(id)value forUndefinedKey:(NSString*)key {
  [self.nativeHandle setValue:value forKey:key];
}

- (void)handlesCloseScriptCommand:(NSCloseCommand*)command {
  if (!_browser) {
    return;
  }

  // GetWindow() can return null during startup.
  if (_browser->GetWindow()) {
    _browser->GetWindow()->Close();
  }
}

@end
