// Copyright 2017 the Chromium Embedded Framework Authors. Portions copyright
// 2014 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.

#include "libcef/browser/extensions/extension_function_details.h"

#include "libcef/browser/browser_context.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/extensions/extension_system.h"
#include "libcef/browser/navigate_params.h"
#include "libcef/browser/thread_util.h"

#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/common/error_utils.h"

using content::RenderViewHost;
using content::WebContents;

namespace extensions {

namespace keys = extensions::tabs_constants;

namespace {

class CefGetExtensionLoadFileCallbackImpl
    : public CefGetExtensionResourceCallback {
 public:
  CefGetExtensionLoadFileCallbackImpl(
      const std::string& file,
      CefExtensionFunctionDetails::LoadFileCallback callback)
      : file_(file), callback_(std::move(callback)) {}

  ~CefGetExtensionLoadFileCallbackImpl() {
    if (!callback_.is_null()) {
      // The callback is still pending. Cancel it now.
      if (CEF_CURRENTLY_ON_UIT()) {
        RunNow(file_, std::move(callback_), nullptr);
      } else {
        CEF_POST_TASK(CEF_UIT, base::BindOnce(
                                   &CefGetExtensionLoadFileCallbackImpl::RunNow,
                                   file_, std::move(callback_), nullptr));
      }
    }
  }

  void Continue(CefRefPtr<CefStreamReader> stream) override {
    if (CEF_CURRENTLY_ON_UIT()) {
      if (!callback_.is_null()) {
        // Always continue asynchronously.
        CEF_POST_TASK(CEF_UIT, base::BindOnce(
                                   &CefGetExtensionLoadFileCallbackImpl::RunNow,
                                   file_, std::move(callback_), stream));
      }
    } else {
      CEF_POST_TASK(CEF_UIT, base::BindOnce(
                                 &CefGetExtensionLoadFileCallbackImpl::Continue,
                                 this, stream));
    }
  }

  void Cancel() override { Continue(nullptr); }

  void Disconnect() { callback_.Reset(); }

 private:
  static void RunNow(const std::string& file,
                     CefExtensionFunctionDetails::LoadFileCallback callback,
                     CefRefPtr<CefStreamReader> stream) {
    CEF_REQUIRE_UIT();

    if (!stream) {
      std::move(callback).Run(nullptr);
      return;
    }

    base::PostTaskAndReplyWithResult(
        FROM_HERE,
        {base::ThreadPool(), base::MayBlock(),
         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
        base::BindOnce(LoadFileFromStream, file, stream), std::move(callback));
  }

  static std::unique_ptr<std::string> LoadFileFromStream(
      const std::string& file,
      CefRefPtr<CefStreamReader> stream) {
    CEF_REQUIRE_BLOCKING();

    // Move to the end of the stream.
    stream->Seek(0, SEEK_END);
    const int64 size = stream->Tell();
    if (size == 0) {
      LOG(WARNING) << "Extension resource " << file << " is empty.";
      return nullptr;
    }

    std::unique_ptr<std::string> result(new std::string());
    result->resize(size);

    // Move to the beginning of the stream.
    stream->Seek(0, SEEK_SET);

    // Read all stream contents into the string.
    int64 read, offset = 0;
    do {
      read =
          static_cast<int>(stream->Read(&(*result)[offset], 1, size - offset));
      offset += read;
    } while (read > 0 && offset < size);

    if (offset != size) {
      LOG(WARNING) << "Extension resource " << file << " read failed; expected "
                   << size << ", got " << offset << " bytes.";
      return nullptr;
    }

    return result;
  }

  const std::string file_;
  CefExtensionFunctionDetails::LoadFileCallback callback_;

  IMPLEMENT_REFCOUNTING(CefGetExtensionLoadFileCallbackImpl);
  DISALLOW_COPY_AND_ASSIGN(CefGetExtensionLoadFileCallbackImpl);
};

}  // namespace

CefExtensionFunctionDetails::CefExtensionFunctionDetails(
    ExtensionFunction* function)
    : function_(function) {}

CefExtensionFunctionDetails::~CefExtensionFunctionDetails() {}

Profile* CefExtensionFunctionDetails::GetProfile() const {
  return Profile::FromBrowserContext(function_->browser_context());
}

CefRefPtr<CefBrowserHostImpl> CefExtensionFunctionDetails::GetSenderBrowser()
    const {
  content::WebContents* web_contents = function_->GetSenderWebContents();
  if (web_contents)
    return CefBrowserHostImpl::GetBrowserForContents(web_contents);
  return nullptr;
}

CefRefPtr<CefBrowserHostImpl> CefExtensionFunctionDetails::GetCurrentBrowser()
    const {
  // Start with the browser hosting the extension.
  CefRefPtr<CefBrowserHostImpl> browser = GetSenderBrowser();
  if (browser && browser->client()) {
    CefRefPtr<CefExtensionHandler> handler = GetCefExtension()->GetHandler();
    if (handler) {
      // Give the handler an opportunity to specify a different browser.
      CefRefPtr<CefBrowser> active_browser =
          handler->GetActiveBrowser(GetCefExtension(), browser.get(),
                                    function_->include_incognito_information());
      if (active_browser && active_browser != browser) {
        CefRefPtr<CefBrowserHostImpl> active_browser_impl =
            static_cast<CefBrowserHostImpl*>(active_browser.get());

        // Make sure we're operating in the same BrowserContextImpl.
        if (CefBrowserContext::GetForContext(browser->GetBrowserContext()) ==
            CefBrowserContext::GetForContext(
                active_browser_impl->GetBrowserContext())) {
          browser = active_browser_impl;
        } else {
          LOG(WARNING) << "Browser with tabId "
                       << active_browser->GetIdentifier()
                       << " cannot be accessed because is uses a different "
                          "CefRequestContext";
        }
      }
    }
  }

  // May be null during startup/shutdown.
  return browser;
}

bool CefExtensionFunctionDetails::CanAccessBrowser(
    CefRefPtr<CefBrowserHostImpl> target) const {
  DCHECK(target);

  // Start with the browser hosting the extension.
  CefRefPtr<CefBrowserHostImpl> browser = GetSenderBrowser();
  if (browser == target) {
    // A sender can always access itself.
    return true;
  }

  if (browser && browser->client()) {
    CefRefPtr<CefExtensionHandler> handler = GetCefExtension()->GetHandler();
    if (handler) {
      return handler->CanAccessBrowser(
          GetCefExtension(), browser.get(),
          function_->include_incognito_information(), target);
    }
  }

  // Default to allowing access.
  return true;
}

CefRefPtr<CefBrowserHostImpl>
CefExtensionFunctionDetails::GetBrowserForTabIdFirstTime(
    int tab_id,
    std::string* error_message) const {
  DCHECK(!get_browser_called_first_time_);
  get_browser_called_first_time_ = true;

  CefRefPtr<CefBrowserHostImpl> browser;

  if (tab_id >= 0) {
    // May be an invalid tabId or in the wrong BrowserContext.
    browser = GetBrowserForTabId(tab_id, function_->browser_context());
    if (!browser || !browser->web_contents() || !CanAccessBrowser(browser)) {
      if (error_message) {
        *error_message = ErrorUtils::FormatErrorMessage(
            keys::kTabNotFoundError, base::NumberToString(tab_id));
      }
      return nullptr;
    }
  } else {
    // May return NULL during shutdown.
    browser = GetCurrentBrowser();
    if (!browser || !browser->web_contents()) {
      if (error_message) {
        *error_message = keys::kNoCurrentWindowError;
      }
      return nullptr;
    }
  }

  return browser;
}

CefRefPtr<CefBrowserHostImpl>
CefExtensionFunctionDetails::GetBrowserForTabIdAgain(
    int tab_id,
    std::string* error_message) const {
  DCHECK_GE(tab_id, 0);
  DCHECK(get_browser_called_first_time_);

  // May return NULL during shutdown.
  CefRefPtr<CefBrowserHostImpl> browser =
      GetBrowserForTabId(tab_id, function_->browser_context());
  if (!browser || !browser->web_contents()) {
    if (error_message) {
      *error_message = ErrorUtils::FormatErrorMessage(
          keys::kTabNotFoundError, base::NumberToString(tab_id));
    }
  }
  return browser;
}

bool CefExtensionFunctionDetails::LoadFile(const std::string& file,
                                           LoadFileCallback callback) const {
  // Start with the browser hosting the extension.
  CefRefPtr<CefBrowserHostImpl> browser = GetSenderBrowser();
  if (browser && browser->client()) {
    CefRefPtr<CefExtensionHandler> handler = GetCefExtension()->GetHandler();
    if (handler) {
      CefRefPtr<CefGetExtensionLoadFileCallbackImpl> cef_callback(
          new CefGetExtensionLoadFileCallbackImpl(file, std::move(callback)));
      if (handler->GetExtensionResource(GetCefExtension(), browser.get(), file,
                                        cef_callback)) {
        return true;
      }
      cef_callback->Disconnect();
    }
  }

  return false;
}

CefExtensionFunctionDetails::OpenTabParams::OpenTabParams() {}

CefExtensionFunctionDetails::OpenTabParams::~OpenTabParams() {}

base::DictionaryValue* CefExtensionFunctionDetails::OpenTab(
    const OpenTabParams& params,
    bool user_gesture,
    std::string* error_message) const {
  CefRefPtr<CefBrowserHostImpl> sender_browser = GetSenderBrowser();
  if (!sender_browser)
    return nullptr;

  // windowId defaults to "current" window.
  int window_id = extension_misc::kCurrentWindowId;
  if (params.window_id.get())
    window_id = *params.window_id;

  // CEF doesn't have the concept of windows containing tab strips so we'll
  // select an "active browser" for BrowserContext sharing instead.
  CefRefPtr<CefBrowserHostImpl> active_browser =
      GetBrowserForTabIdFirstTime(window_id, error_message);
  if (!active_browser)
    return nullptr;

  // If an opener browser was specified then we expect it to exist.
  int opener_browser_id = -1;
  if (params.opener_tab_id.get() && *params.opener_tab_id >= 0) {
    if (GetBrowserForTabIdAgain(*params.opener_tab_id, error_message)) {
      opener_browser_id = *params.opener_tab_id;
    } else {
      return nullptr;
    }
  }

  GURL url;
  if (params.url.get()) {
    std::string url_string = *params.url;
    url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string,
                                                       function()->extension());
    if (!url.is_valid()) {
      if (error_message) {
        *error_message =
            ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string);
      }
      return nullptr;
    }
  }

  // Don't let extensions crash the browser or renderers.
  if (ExtensionTabUtil::IsKillURL(url)) {
    if (error_message)
      *error_message = keys::kNoCrashBrowserError;
    return nullptr;
  }

  // Default to foreground for the new tab. The presence of 'active' property
  // will override this default.
  bool active = true;
  if (params.active.get())
    active = *params.active;

  // CEF doesn't use the index value but we let the client see/modify it.
  int index = 0;
  if (params.index.get())
    index = *params.index;

  CefBrowserContext* browser_context_impl =
      CefBrowserContext::GetForContext(active_browser->GetBrowserContext());

  // A CEF representation should always exist.
  CefRefPtr<CefExtension> cef_extension =
      browser_context_impl->extension_system()->GetExtension(
          function()->extension()->id());
  DCHECK(cef_extension);
  if (!cef_extension)
    return nullptr;

  // Always use the same request context that the extension was registered with.
  // GetLoaderContext() will return NULL for internal extensions.
  CefRefPtr<CefRequestContext> request_context =
      cef_extension->GetLoaderContext();
  if (!request_context)
    return nullptr;

  CefBrowserHostImpl::CreateParams create_params;
  create_params.url = url;
  create_params.request_context = request_context;
  create_params.window_info.reset(new CefWindowInfo);

#if defined(OS_WIN)
  create_params.window_info->SetAsPopup(nullptr, CefString());
#endif

  // Start with the active browser's settings.
  create_params.client = active_browser->GetClient();
  create_params.settings = active_browser->settings();

  CefRefPtr<CefExtensionHandler> handler = cef_extension->GetHandler();
  if (handler.get() &&
      handler->OnBeforeBrowser(cef_extension, sender_browser.get(),
                               active_browser.get(), index, url.spec(), active,
                               *create_params.window_info, create_params.client,
                               create_params.settings)) {
    // Cancel the browser creation.
    return nullptr;
  }

  if (active_browser->IsViewsHosted()) {
    // The new browser will also be Views hosted.
    create_params.window_info.reset();
  }

  // Browser creation may fail under certain rare circumstances.
  CefRefPtr<CefBrowserHostImpl> new_browser =
      CefBrowserHostImpl::Create(create_params);
  if (!new_browser)
    return nullptr;

  // Return data about the newly created tab.
  auto extension = function()->extension();
  auto web_contents = new_browser->web_contents();
  auto result = CreateTabObject(new_browser, opener_browser_id, active, index);
  auto scrub_tab_behavior = ExtensionTabUtil::GetScrubTabBehavior(
      extension, extensions::Feature::Context::UNSPECIFIED_CONTEXT,
      web_contents);
  ExtensionTabUtil::ScrubTabForExtension(extension, web_contents, result.get(),
                                         scrub_tab_behavior);
  return result->ToValue().release();
}

std::unique_ptr<api::tabs::Tab> CefExtensionFunctionDetails::CreateTabObject(
    CefRefPtr<CefBrowserHostImpl> new_browser,
    int opener_browser_id,
    bool active,
    int index) const {
  content::WebContents* contents = new_browser->web_contents();

  bool is_loading = contents->IsLoading();
  auto tab_object = std::make_unique<api::tabs::Tab>();
  tab_object->id = std::make_unique<int>(new_browser->GetIdentifier());
  tab_object->index = index;
  tab_object->window_id = *tab_object->id;
  tab_object->status = is_loading ? api::tabs::TAB_STATUS_LOADING
                                  : api::tabs::TAB_STATUS_COMPLETE;
  tab_object->active = active;
  tab_object->selected = true;
  tab_object->highlighted = true;
  tab_object->pinned = false;
  // TODO(extensions): Use RecentlyAudibleHelper to populate |audible|.
  tab_object->discarded = false;
  tab_object->auto_discardable = false;
  tab_object->muted_info = CreateMutedInfo(contents);
  tab_object->incognito = false;
  gfx::Size contents_size = contents->GetContainerBounds().size();
  tab_object->width = std::make_unique<int>(contents_size.width());
  tab_object->height = std::make_unique<int>(contents_size.height());
  tab_object->url = std::make_unique<std::string>(contents->GetURL().spec());
  tab_object->title =
      std::make_unique<std::string>(base::UTF16ToUTF8(contents->GetTitle()));

  content::NavigationEntry* entry = contents->GetController().GetVisibleEntry();
  if (entry && entry->GetFavicon().valid) {
    tab_object->fav_icon_url =
        std::make_unique<std::string>(entry->GetFavicon().url.spec());
  }

  if (opener_browser_id >= 0)
    tab_object->opener_tab_id = std::make_unique<int>(opener_browser_id);

  return tab_object;
}

// static
std::unique_ptr<api::tabs::MutedInfo>
CefExtensionFunctionDetails::CreateMutedInfo(content::WebContents* contents) {
  DCHECK(contents);
  std::unique_ptr<api::tabs::MutedInfo> info(new api::tabs::MutedInfo);
  info->muted = contents->IsAudioMuted();
  // TODO(cef): Maybe populate |info->reason|.
  return info;
}

CefRefPtr<CefExtension> CefExtensionFunctionDetails::GetCefExtension() const {
  if (!cef_extension_) {
    cef_extension_ =
        static_cast<CefBrowserContext*>(function_->browser_context())
            ->extension_system()
            ->GetExtension(function_->extension_id());
    DCHECK(cef_extension_);
  }
  return cef_extension_;
}

}  // namespace extensions
