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

#include "build/build_config.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/notification_types.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

ExtensionErrorReporter* ExtensionErrorReporter::instance_ = NULL;

// static
void ExtensionErrorReporter::Init(bool enable_noisy_errors) {
  if (!instance_) {
    instance_ = new ExtensionErrorReporter(enable_noisy_errors);
  }
}

// static
ExtensionErrorReporter* ExtensionErrorReporter::GetInstance() {
  CHECK(instance_) << "Init() was never called";
  return instance_;
}

ExtensionErrorReporter::ExtensionErrorReporter(bool enable_noisy_errors)
    : ui_loop_(base::MessageLoop::current()),
      enable_noisy_errors_(enable_noisy_errors) {
}

ExtensionErrorReporter::~ExtensionErrorReporter() {}

void ExtensionErrorReporter::ReportLoadError(
    const base::FilePath& extension_path,
    const std::string& error,
    content::BrowserContext* browser_context,
    bool be_noisy) {
  content::NotificationService::current()->Notify(
      extensions::NOTIFICATION_EXTENSION_LOAD_ERROR,
      content::Source<Profile>(Profile::FromBrowserContext(browser_context)),
      content::Details<const std::string>(&error));

  std::string path_str = base::UTF16ToUTF8(extension_path.LossyDisplayName());
  base::string16 message = base::UTF8ToUTF16(base::StringPrintf(
      "%s %s. %s",
      l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE).c_str(),
      path_str.c_str(),
      error.c_str()));
  ReportError(message, be_noisy);
  FOR_EACH_OBSERVER(Observer,
                    observers_,
                    OnLoadFailure(browser_context, extension_path, error));
}

void ExtensionErrorReporter::ReportError(const base::string16& message,
                                         bool be_noisy) {
  // NOTE: There won't be a ui_loop_ in the unit test environment.
  if (ui_loop_) {
    CHECK(base::MessageLoop::current() == ui_loop_)
        << "ReportError can only be called from the UI thread.";
  }

  errors_.push_back(message);

  // TODO(aa): Print the error message out somewhere better. I think we are
  // going to need some sort of 'extension inspector'.
  LOG(WARNING) << "Extension error: " << message;

  if (enable_noisy_errors_ && be_noisy) {
    chrome::ShowMessageBox(
        NULL,
        l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_ERROR_HEADING),
        message,
        chrome::MESSAGE_BOX_TYPE_WARNING);
  }
}

const std::vector<base::string16>* ExtensionErrorReporter::GetErrors() {
  return &errors_;
}

void ExtensionErrorReporter::ClearErrors() {
  errors_.clear();
}

void ExtensionErrorReporter::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void ExtensionErrorReporter::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}
