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

#include "chrome/browser/plugins/plugin_installer.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/process/process.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/download/download_stats.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/plugins/plugin_installer_observer.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_url_parameters.h"
#include "content/public/browser/web_contents.h"

using content::DownloadItem;

PluginInstaller::PluginInstaller()
    : state_(INSTALLER_STATE_IDLE),
      strong_observer_count_(0) {
}

PluginInstaller::~PluginInstaller() {
}

void PluginInstaller::OnDownloadUpdated(DownloadItem* download) {
  DownloadItem::DownloadState state = download->GetState();
  switch (state) {
    case DownloadItem::IN_PROGRESS:
      return;
    case DownloadItem::COMPLETE: {
      DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
      state_ = INSTALLER_STATE_IDLE;
      FOR_EACH_OBSERVER(PluginInstallerObserver, observers_,
                        DownloadFinished());
      break;
    }
    case DownloadItem::CANCELLED: {
      DownloadCancelled();
      break;
    }
    case DownloadItem::INTERRUPTED: {
      content::DownloadInterruptReason reason = download->GetLastReason();
      DownloadError(content::DownloadInterruptReasonToString(reason));
      break;
    }
    case DownloadItem::MAX_DOWNLOAD_STATE: {
      NOTREACHED();
      return;
    }
  }
  download->RemoveObserver(this);
}

void PluginInstaller::OnDownloadDestroyed(DownloadItem* download) {
  DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
  state_ = INSTALLER_STATE_IDLE;
  download->RemoveObserver(this);
}

void PluginInstaller::AddObserver(PluginInstallerObserver* observer) {
  strong_observer_count_++;
  observers_.AddObserver(observer);
}

void PluginInstaller::RemoveObserver(PluginInstallerObserver* observer) {
  strong_observer_count_--;
  observers_.RemoveObserver(observer);
  if (strong_observer_count_ == 0) {
    FOR_EACH_OBSERVER(WeakPluginInstallerObserver, weak_observers_,
                      OnlyWeakObserversLeft());
  }
}

void PluginInstaller::AddWeakObserver(WeakPluginInstallerObserver* observer) {
  weak_observers_.AddObserver(observer);
}

void PluginInstaller::RemoveWeakObserver(
    WeakPluginInstallerObserver* observer) {
  weak_observers_.RemoveObserver(observer);
}

void PluginInstaller::StartInstalling(const GURL& plugin_url,
                                      content::WebContents* web_contents) {
  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(
          web_contents->GetBrowserContext());
  StartInstallingWithDownloadManager(
      plugin_url, web_contents, download_manager);
}

void PluginInstaller::StartInstallingWithDownloadManager(
    const GURL& plugin_url,
    content::WebContents* web_contents,
    content::DownloadManager* download_manager) {
  DCHECK_EQ(INSTALLER_STATE_IDLE, state_);
  state_ = INSTALLER_STATE_DOWNLOADING;
  FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadStarted());
  scoped_ptr<content::DownloadUrlParameters> download_parameters(
      content::DownloadUrlParameters::FromWebContents(web_contents,
                                                      plugin_url));
  download_parameters->set_callback(
      base::Bind(&PluginInstaller::DownloadStarted, base::Unretained(this)));
  RecordDownloadSource(DOWNLOAD_INITIATED_BY_PLUGIN_INSTALLER);
  download_manager->DownloadUrl(download_parameters.Pass());
}

void PluginInstaller::DownloadStarted(
    content::DownloadItem* item,
    content::DownloadInterruptReason interrupt_reason) {
  if (interrupt_reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) {
    std::string msg = base::StringPrintf(
        "Error %d: %s",
        interrupt_reason,
        content::DownloadInterruptReasonToString(interrupt_reason).c_str());
    DownloadError(msg);
    return;
  }
  item->SetOpenWhenComplete(true);
  item->AddObserver(this);
}

void PluginInstaller::OpenDownloadURL(const GURL& plugin_url,
                                      content::WebContents* web_contents) {
  DCHECK_EQ(INSTALLER_STATE_IDLE, state_);
  web_contents->OpenURL(content::OpenURLParams(
      plugin_url,
      content::Referrer(web_contents->GetURL(),
                        blink::WebReferrerPolicyDefault),
      NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_TYPED, false));
  FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadFinished());
}

void PluginInstaller::DownloadError(const std::string& msg) {
  DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
  state_ = INSTALLER_STATE_IDLE;
  FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadError(msg));
}

void PluginInstaller::DownloadCancelled() {
  DCHECK_EQ(INSTALLER_STATE_DOWNLOADING, state_);
  state_ = INSTALLER_STATE_IDLE;
  FOR_EACH_OBSERVER(PluginInstallerObserver, observers_, DownloadCancelled());
}
