// Copyright (c) 2012 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.

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

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#import "base/mac/scoped_nsobject.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/sessions/session_tab_helper.h"
#include "chrome/browser/ui/cocoa/applescript/apple_event_util.h"
#include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
#include "chrome/browser/ui/cocoa/applescript/metrics_applescript.h"
#include "chrome/common/chrome_isolated_world_ids.h"
#include "chrome/common/url_constants.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::RenderFrameHost;
using content::RenderViewHost;
using content::Referrer;
using content::WebContents;

namespace {

void ResumeAppleEventAndSendReply(NSAppleEventManagerSuspensionID suspension_id,
                                  const 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()
@property (nonatomic, copy) NSString* tempURL;
@end

@implementation TabAppleScript

@synthesize tempURL = tempURL_;

- (instancetype)init {
  if ((self = [super init])) {
    SessionID session;
    SessionID::id_type futureSessionIDOfTab = session.id() + 1;
    // Holds the SessionID that the new tab is going to get.
    base::scoped_nsobject<NSNumber> numID(
        [[NSNumber alloc] initWithInt:futureSessionIDOfTab]);
    [self setUniqueID:numID];
  }
  return self;
}

- (void)dealloc {
  [tempURL_ release];
  [super dealloc];
}

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

  if ((self = [super init])) {
    // It is safe to be weak; if a tab goes away (e.g. the user closes a tab)
    // the AppleScript runtime calls tabs in AppleScriptWindow and this
    // particular tab is never returned.
    webContents_ = webContents;
    profile_ = Profile::FromBrowserContext(webContents->GetBrowserContext());
    SessionTabHelper* session_tab_helper =
        SessionTabHelper::FromWebContents(webContents);
    base::scoped_nsobject<NSNumber> numID(
        [[NSNumber alloc] initWithInt:session_tab_helper->session_id().id()]);
    [self setUniqueID:numID];
  }
  return self;
}

- (void)setWebContents:(content::WebContents*)webContents {
  DCHECK(webContents);
  // It is safe to be weak; if a tab goes away (e.g. the user closes a tab)
  // the AppleScript runtime calls tabs in AppleScriptWindow and this
  // particular tab is never returned.
  webContents_ = webContents;
  SessionTabHelper* session_tab_helper =
      SessionTabHelper::FromWebContents(webContents);
  base::scoped_nsobject<NSNumber> numID(
      [[NSNumber alloc] initWithInt:session_tab_helper->session_id().id()]);
  [self setUniqueID:numID];

  if ([self tempURL])
    [self setURL:[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*)aURL {
  GURL url(base::SysNSStringToUTF8(aURL));
  if (!chrome::mac::IsJavaScriptEnabledForProfile(profile_) &&
      url.SchemeIs(url::kJavaScriptScheme)) {
    AppleScript::SetError(AppleScript::errJavaScriptUnsupported);
    return;
  }

  // If a scripter sets a URL before the node is added save it at a temporary
  // location.
  if (!webContents_) {
    [self setTempURL:aURL];
    return;
  }

  // check for valid url.
  if (!url.is_empty() && !url.is_valid()) {
    AppleScript::SetError(AppleScript::errInvalidURL);
    return;
  }

  NavigationEntry* entry = webContents_->GetController().GetActiveEntry();
  if (!entry)
    return;

  const GURL& previousURL = entry->GetVirtualURL();
  webContents_->OpenURL(OpenURLParams(
      url, content::Referrer(previousURL, blink::kWebReferrerPolicyDefault),
      WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));
}

- (NSString*)title {
  NavigationEntry* entry = webContents_->GetController().GetActiveEntry();
  if (!entry)
    return nil;

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

- (NSNumber*)loading {
  BOOL loadingValue = webContents_->IsLoading() ? YES : NO;
  return [NSNumber numberWithBool:loadingValue];
}

- (void)handlesUndoScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_UNDO);
  webContents_->Undo();
}

- (void)handlesRedoScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_REDO);
  webContents_->Redo();
}

- (void)handlesCutScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_CUT);
  webContents_->Cut();
}

- (void)handlesCopyScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_COPY);
  webContents_->Copy();
}

- (void)handlesPasteScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_PASTE);
  webContents_->Paste();
}

- (void)handlesSelectAllScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(
      AppleScript::AppleScriptCommand::TAB_SELECT_ALL);
  webContents_->SelectAll();
}

- (void)handlesGoBackScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_GO_BACK);
  NavigationController& navigationController = webContents_->GetController();
  if (navigationController.CanGoBack())
    navigationController.GoBack();
}

- (void)handlesGoForwardScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(
      AppleScript::AppleScriptCommand::TAB_GO_FORWARD);
  NavigationController& navigationController = webContents_->GetController();
  if (navigationController.CanGoForward())
    navigationController.GoForward();
}

- (void)handlesReloadScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_RELOAD);
  NavigationController& navigationController = webContents_->GetController();
  const bool checkForRepost = true;
  navigationController.Reload(content::ReloadType::NORMAL, checkForRepost);
}

- (void)handlesStopScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_STOP);
  webContents_->Stop();
}

- (void)handlesPrintScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_PRINT);
  bool initiated = printing::PrintViewManager::FromWebContents(webContents_)
                       ->PrintNow(webContents_->GetMainFrame());
  if (!initiated) {
    AppleScript::SetError(AppleScript::errInitiatePrinting);
  }
}

- (void)handlesSaveScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_SAVE);
  NSDictionary* dictionary = [command evaluatedArguments];

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

  base::FilePath mainFile(base::SysNSStringToUTF8([fileURL path]));
  // 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 objectForKey:@"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 {
      AppleScript::SetError(AppleScript::errInvalidSaveType);
      return;
    }
  }

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

- (void)handlesCloseScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(AppleScript::AppleScriptCommand::TAB_CLOSE);
  webContents_->GetDelegate()->CloseContents(webContents_);
}

- (void)handlesViewSourceScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(
      AppleScript::AppleScriptCommand::TAB_VIEW_SOURCE);
  NavigationEntry* entry =
      webContents_->GetController().GetLastCommittedEntry();
  if (entry) {
    webContents_->OpenURL(
        OpenURLParams(GURL(content::kViewSourceScheme + std::string(":") +
                           entry->GetURL().spec()),
                      Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
                      ui::PAGE_TRANSITION_LINK, false));
  }
}

- (id)handlesExecuteJavascriptScriptCommand:(NSScriptCommand*)command {
  AppleScript::LogAppleScriptUMA(
      AppleScript::AppleScriptCommand::TAB_EXECUTE_JAVASCRIPT);

  if (!chrome::mac::IsJavaScriptEnabledForProfile(profile_)) {
    AppleScript::SetError(AppleScript::errJavaScriptUnsupported);
    return nil;
  }

  content::RenderFrameHost* frame = webContents_->GetMainFrame();
  if (!frame) {
    NOTREACHED();
    return nil;
  }

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

  base::string16 script = base::SysNSStringToUTF16(
      [[command evaluatedArguments] objectForKey:@"javascript"]);
  frame->ExecuteJavaScriptInIsolatedWorld(script, callback,
                                          ISOLATED_WORLD_ID_APPLESCRIPT);

  return nil;
}

@end
