// 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.
//
// Download code which handles CRX files (extensions, themes, apps, ...).

#include "chrome/browser/download/download_crx_util.h"

#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/notification_service.h"
#include "extensions/common/user_script.h"

using content::BrowserThread;
using content::DownloadItem;
using extensions::WebstoreInstaller;

namespace download_crx_util {

namespace {

// Hold a mock ExtensionInstallPrompt object that will be used when the
// download system opens a CRX.
ExtensionInstallPrompt* mock_install_prompt_for_testing = NULL;

// Called to get an extension install UI object.  In tests, will return
// a mock if the test calls download_util::SetMockInstallPromptForTesting()
// to set one.
scoped_ptr<ExtensionInstallPrompt> CreateExtensionInstallPrompt(
    Profile* profile,
    const DownloadItem& download_item) {
  // Use a mock if one is present.  Otherwise, create a real extensions
  // install UI.
  if (mock_install_prompt_for_testing) {
    ExtensionInstallPrompt* result = mock_install_prompt_for_testing;
    mock_install_prompt_for_testing = NULL;
    return scoped_ptr<ExtensionInstallPrompt>(result);
  } else {
    content::WebContents* web_contents = download_item.GetWebContents();
    if (!web_contents) {
      chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop();
      Browser* browser = chrome::FindLastActiveWithProfile(profile,
          active_desktop);
      if (!browser)
        browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
                                                    profile, active_desktop));
      web_contents = browser->tab_strip_model()->GetActiveWebContents();
    }
    return scoped_ptr<ExtensionInstallPrompt>(
        new ExtensionInstallPrompt(web_contents));
  }
}

}  // namespace

// Tests can call this method to inject a mock ExtensionInstallPrompt
// to be used to confirm permissions on a downloaded CRX.
void SetMockInstallPromptForTesting(
    scoped_ptr<ExtensionInstallPrompt> mock_prompt) {
  mock_install_prompt_for_testing = mock_prompt.release();
}

scoped_refptr<extensions::CrxInstaller> OpenChromeExtension(
    Profile* profile,
    const DownloadItem& download_item) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  ExtensionService* service = extensions::ExtensionSystem::Get(profile)->
      extension_service();
  CHECK(service);

  scoped_refptr<extensions::CrxInstaller> installer(
      extensions::CrxInstaller::Create(
          service,
          CreateExtensionInstallPrompt(profile, download_item),
          WebstoreInstaller::GetAssociatedApproval(download_item)));

  installer->set_error_on_unsupported_requirements(true);
  installer->set_delete_source(true);
  installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);

  if (OffStoreInstallAllowedByPrefs(profile, download_item)) {
    installer->set_off_store_install_allow_reason(
        extensions::CrxInstaller::OffStoreInstallAllowedBecausePref);
  }

  if (extensions::UserScript::IsURLUserScript(download_item.GetURL(),
                                              download_item.GetMimeType())) {
    installer->InstallUserScript(download_item.GetFullPath(),
                                 download_item.GetURL());
  } else {
    bool is_gallery_download =
        WebstoreInstaller::GetAssociatedApproval(download_item) != NULL;
    installer->set_original_mime_type(download_item.GetOriginalMimeType());
    installer->set_apps_require_extension_mime_type(true);
    installer->set_download_url(download_item.GetURL());
    installer->set_is_gallery_install(is_gallery_download);
    if (is_gallery_download)
      installer->set_original_download_url(download_item.GetOriginalUrl());
    installer->set_allow_silent_install(is_gallery_download);
    installer->InstallCrx(download_item.GetFullPath());
  }

  return installer;
}

bool IsExtensionDownload(const DownloadItem& download_item) {
  if (download_item.GetTargetDisposition() ==
      DownloadItem::TARGET_DISPOSITION_PROMPT)
    return false;

  if (download_item.GetMimeType() == extensions::Extension::kMimeType ||
      extensions::UserScript::IsURLUserScript(download_item.GetURL(),
                                              download_item.GetMimeType())) {
    return true;
  } else {
    return false;
  }
}

bool OffStoreInstallAllowedByPrefs(Profile* profile, const DownloadItem& item) {
  ExtensionService* service = extensions::ExtensionSystem::Get(
      profile)->extension_service();
  if (!service)
    return false;

  extensions::ExtensionPrefs* prefs = service->extension_prefs();
  CHECK(prefs);

  extensions::URLPatternSet url_patterns = prefs->GetAllowedInstallSites();

  if (!url_patterns.MatchesURL(item.GetURL()))
    return false;

  // The referrer URL must also be whitelisted, unless the URL has the file
  // scheme (there's no referrer for those URLs).
  // TODO(aa): RefererURL is cleared in some cases, for example when going
  // between secure and non-secure URLs. It would be better if DownloadItem
  // tracked the initiating page explicitly.
  return url_patterns.MatchesURL(item.GetReferrerUrl()) ||
         item.GetURL().SchemeIsFile();
}

}  // namespace download_crx_util
