// 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/tab_applescript.h"

#include "base/apple/foundation_util.h"
#include "base/check.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/cocoa/applescript/apple_event_util.h"
#include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
#include "chrome/common/chrome_isolated_world_ids.h"
#include "chrome/common/url_constants.h"
#include "components/sessions/content/session_tab_helper.h"
#include "components/sessions/core/session_id.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/save_page_type.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "url/gurl.h"

using content::NavigationController;
using content::NavigationEntry;
using content::OpenURLParams;
using content::Referrer;
using content::RenderFrameHost;
using content::RenderViewHost;
using content::WebContents;

namespace {

void ResumeAppleEventAndSendReply(NSAppleEventManagerSuspensionID suspension_id,
                                  base::Value result_value) {
  NSAppleEventDescriptor* result_descriptor =
      chrome::mac::ValueToAppleEventDescriptor(result_value);

  NSAppleEventManager* manager = [NSAppleEventManager sharedAppleEventManager];
  NSAppleEventDescriptor* reply_event =
      [manager replyAppleEventForSuspensionID:suspension_id];
  [reply_event setParamDescriptor:result_descriptor forKeyword:keyDirectObject];
  [manager resumeWithSuspensionID:suspension_id];
}

}  // namespace

@interface TabAppleScript ()

// Contains the temporary URL when a user creates a new folder/item with the URL
// specified like:
//
//   make new tab with properties {URL:"http://google.com"}
@property(nonatomic, copy) NSString* tempURL;

- (bool)isJavaScriptEnabled;

@end

@implementation TabAppleScript {
  // 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<content::WebContents> _webContents;
}

@synthesize tempURL = _tempURL;

- (bool)isJavaScriptEnabled {
  if (!_webContents) {
    return false;
  }

  return chrome::mac::IsJavaScriptEnabledForProfile(
      Profile::FromBrowserContext(_webContents->GetBrowserContext()));
}

- (instancetype)init {
  if ((self = [super init])) {
    // Holds the SessionID that the new tab is going to get.
    SessionID::id_type futureSessionIDOfTab = SessionID::NewUnique().id() + 1;
    self.uniqueID = [NSString stringWithFormat:@"%d", futureSessionIDOfTab];
  }
  return self;
}

- (instancetype)initWithWebContents:(content::WebContents*)webContents {
  if (!webContents) {
    return nil;
  }

  if ((self = [super init])) {
    _webContents = webContents->GetWeakPtr();

    sessions::SessionTabHelper* session_tab_helper =
        sessions::SessionTabHelper::FromWebContents(webContents);
    self.uniqueID = [NSString
        stringWithFormat:@"%d", session_tab_helper->session_id().id()];
  }
  return self;
}

- (void)setWebContents:(content::WebContents*)webContents {
  DCHECK(webContents);
  _webContents = webContents->GetWeakPtr();

  sessions::SessionTabHelper* session_tab_helper =
      sessions::SessionTabHelper::FromWebContents(webContents);
  self.uniqueID =
      [NSString stringWithFormat:@"%d", session_tab_helper->session_id().id()];

  if (self.tempURL) {
    self.URL = self.tempURL;
  }
}

- (NSString*)URL {
  if (!_webContents) {
    return nil;
  }

  NavigationEntry* entry = _webContents->GetController().GetActiveEntry();
  if (!entry) {
    return nil;
  }
  const GURL& url = entry->GetVirtualURL();
  return base::SysUTF8ToNSString(url.spec());
}

- (void)setURL:(NSString*)url {
  // If a scripter sets a URL before |webContents_| or |profile_| is set, save
  // it at a temporary location. Once they're set, -setURL: will be call again
  // with the temporary URL.
  if (!_webContents) {
    self.tempURL = url;
    return;
  }

  GURL gurl(base::SysNSStringToUTF8(url));
  if (![self isJavaScriptEnabled] && gurl.SchemeIs(url::kJavaScriptScheme)) {
    AppleScript::SetError(AppleScript::Error::kJavaScriptUnsupported);
    return;
  }

  // Check if the URL is valid; if not, then attempting to open it will trip
  // a fatal check in navigation.
  if (!gurl.is_valid()) {
    AppleScript::SetError(AppleScript::Error::kInvalidURL);
    return;
  }

  NavigationEntry* entry = _webContents->GetController().GetActiveEntry();
  if (!entry) {
    return;
  }

  _webContents->OpenURL(OpenURLParams(gurl, content::Referrer(),
                                      WindowOpenDisposition::CURRENT_TAB,
                                      ui::PAGE_TRANSITION_TYPED, false),
                        /*navigation_handle_callback=*/{});
}

- (NSString*)title {
  if (!_webContents) {
    return nil;
  }

  NavigationEntry* entry = _webContents->GetController().GetActiveEntry();
  if (!entry) {
    return nil;
  }

  std::u16string title = entry ? entry->GetTitle() : std::u16string();
  return base::SysUTF16ToNSString(title);
}

- (NSNumber*)loading {
  if (!_webContents) {
    return nil;
  }

  BOOL loadingValue = _webContents->IsLoading() ? YES : NO;
  return @(loadingValue);
}

- (void)handlesUndoScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Undo();
}

- (void)handlesRedoScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Redo();
}

- (void)handlesCutScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Cut();
}

- (void)handlesCopyScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Copy();
}

- (void)handlesPasteScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Paste();
}

- (void)handlesSelectAllScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->SelectAll();
}

- (void)handlesGoBackScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  NavigationController& navigationController = _webContents->GetController();
  if (navigationController.CanGoBack()) {
    navigationController.GoBack();
  }
}

- (void)handlesGoForwardScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  NavigationController& navigationController = _webContents->GetController();
  if (navigationController.CanGoForward()) {
    navigationController.GoForward();
  }
}

- (void)handlesReloadScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  NavigationController& navigationController = _webContents->GetController();
  navigationController.Reload(content::ReloadType::NORMAL,
                              /*check_for_repost=*/true);
}

- (void)handlesStopScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->Stop();
}

- (void)handlesPrintScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  bool initiated =
      printing::PrintViewManager::FromWebContents(_webContents.get())
          ->PrintNow(_webContents->GetPrimaryMainFrame());
  if (!initiated) {
    AppleScript::SetError(AppleScript::Error::kInitiatePrinting);
  }
}

- (void)handlesSaveScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  NSDictionary* dictionary = command.evaluatedArguments;

  NSURL* fileURL = dictionary[@"File"];
  // Scripter has not specified the location at which to save, so we prompt for
  // it.
  if (!fileURL) {
    _webContents->OnSavePage();
    return;
  }

  base::FilePath mainFile = base::apple::NSURLToFilePath(fileURL);
  // We create a directory path at the folder within which the file exists.
  // Eg.    if main_file = '/Users/Foo/Documents/Google.html'
  // then directory_path = '/Users/Foo/Documents/Google_files/'.
  base::FilePath directoryPath = mainFile.RemoveExtension();
  directoryPath = directoryPath.InsertBeforeExtension(std::string("_files/"));

  NSString* saveType = dictionary[@"FileType"];

  content::SavePageType savePageType = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
  if (saveType) {
    if ([saveType isEqualToString:@"only html"]) {
      savePageType = content::SAVE_PAGE_TYPE_AS_ONLY_HTML;
    } else if ([saveType isEqualToString:@"complete html"]) {
      savePageType = content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML;
    } else if ([saveType isEqualToString:@"single file"]) {
      savePageType = content::SAVE_PAGE_TYPE_AS_MHTML;
    } else {
      AppleScript::SetError(AppleScript::Error::kInvalidSaveType);
      return;
    }
  }

  _webContents->SavePage(mainFile, directoryPath, savePageType);
}

- (void)handlesCloseScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->GetDelegate()->CloseContents(_webContents.get());
}

- (void)handlesViewSourceScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return;
  }

  _webContents->GetPrimaryMainFrame()->ViewSource();
}

- (id)handlesExecuteJavascriptScriptCommand:(NSScriptCommand*)command {
  if (!_webContents) {
    return nil;
  }

  if (![self isJavaScriptEnabled]) {
    AppleScript::SetError(AppleScript::Error::kJavaScriptUnsupported);
    return nil;
  }

  content::RenderFrameHost* frame = _webContents->GetPrimaryMainFrame();
  if (!frame) {
    return nil;
  }

  NSAppleEventManager* manager = [NSAppleEventManager sharedAppleEventManager];
  NSAppleEventManagerSuspensionID suspensionID =
      [manager suspendCurrentAppleEvent];
  content::RenderFrameHost::JavaScriptResultCallback callback =
      base::BindOnce(&ResumeAppleEventAndSendReply, suspensionID);

  std::u16string script =
      base::SysNSStringToUTF16(command.evaluatedArguments[@"javascript"]);
  frame->ExecuteJavaScriptInIsolatedWorld(script, std::move(callback),
                                          ISOLATED_WORLD_ID_APPLESCRIPT);

  return nil;
}

@end
