// 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/ui/webui/instant_ui.h"

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/search/instant_controller.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "grit/browser_resources.h"

namespace {

content::WebUIDataSource* CreateInstantHTMLSource() {
  content::WebUIDataSource* source =
      content::WebUIDataSource::Create(chrome::kChromeUIInstantHost);
  source->SetJsonPath("strings.js");
  source->AddResourcePath("instant.js", IDR_INSTANT_JS);
  source->AddResourcePath("instant.css", IDR_INSTANT_CSS);
  source->SetDefaultResource(IDR_INSTANT_HTML);
  return source;
}

std::string FormatTime(int64 time) {
  base::Time::Exploded exploded;
  base::Time::FromInternalValue(time).UTCExplode(&exploded);
  return base::StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%03d",
      exploded.year, exploded.month, exploded.day_of_month,
      exploded.hour, exploded.minute, exploded.second, exploded.millisecond);
}

// This class receives JavaScript messages from the renderer.
// Note that the WebUI infrastructure runs on the UI thread, therefore all of
// this class's methods are expected to run on the UI thread.
class InstantUIMessageHandler
    : public content::WebUIMessageHandler,
      public base::SupportsWeakPtr<InstantUIMessageHandler> {
 public:
  InstantUIMessageHandler();
  virtual ~InstantUIMessageHandler();

  // WebUIMessageHandler implementation.
  virtual void RegisterMessages() OVERRIDE;

 private:
  void GetPreferenceValue(const base::ListValue* args);
  void SetPreferenceValue(const base::ListValue* args);
  void GetDebugInfo(const base::ListValue* value);
  void ClearDebugInfo(const base::ListValue* value);

  DISALLOW_COPY_AND_ASSIGN(InstantUIMessageHandler);
};

InstantUIMessageHandler::InstantUIMessageHandler() {}

InstantUIMessageHandler::~InstantUIMessageHandler() {}

void InstantUIMessageHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "getPreferenceValue",
      base::Bind(&InstantUIMessageHandler::GetPreferenceValue,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "setPreferenceValue",
      base::Bind(&InstantUIMessageHandler::SetPreferenceValue,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getDebugInfo",
      base::Bind(&InstantUIMessageHandler::GetDebugInfo,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "clearDebugInfo",
      base::Bind(&InstantUIMessageHandler::ClearDebugInfo,
                 base::Unretained(this)));
}

void InstantUIMessageHandler::GetPreferenceValue(const base::ListValue* args) {
  std::string pref_name;
  if (!args->GetString(0, &pref_name)) return;

  base::StringValue pref_name_value(pref_name);
  if (pref_name == prefs::kInstantUIZeroSuggestUrlPrefix) {
    PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
    base::StringValue arg(prefs->GetString(pref_name.c_str()));
    web_ui()->CallJavascriptFunction(
        "instantConfig.getPreferenceValueResult", pref_name_value, arg);
  }
}

void InstantUIMessageHandler::SetPreferenceValue(const base::ListValue* args) {
  std::string pref_name;
  if (!args->GetString(0, &pref_name)) return;

  if (pref_name == prefs::kInstantUIZeroSuggestUrlPrefix) {
    std::string value;
    if (!args->GetString(1, &value))
      return;
    PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
    prefs->SetString(pref_name.c_str(), value);
  }
}

void InstantUIMessageHandler::GetDebugInfo(const base::ListValue* args) {
#if !defined(OS_ANDROID)
  typedef std::pair<int64, std::string> DebugEvent;

  if (!web_ui()->GetWebContents())
    return;
  Browser* browser = chrome::FindBrowserWithWebContents(
      web_ui()->GetWebContents());
  if (!browser || !browser->instant_controller())
    return;

  InstantController* instant = browser->instant_controller()->instant();
  const std::list<DebugEvent>& events = instant->debug_events();

  base::DictionaryValue data;
  base::ListValue* entries = new base::ListValue();
  for (std::list<DebugEvent>::const_iterator it = events.begin();
       it != events.end(); ++it) {
    base::DictionaryValue* entry = new base::DictionaryValue();
    entry->SetString("time", FormatTime(it->first));
    entry->SetString("text", it->second);
    entries->Append(entry);
  }
  data.Set("entries", entries);

  web_ui()->CallJavascriptFunction("instantConfig.getDebugInfoResult", data);
#endif
}

void InstantUIMessageHandler::ClearDebugInfo(const base::ListValue* args) {
#if !defined(OS_ANDROID)
  if (!web_ui()->GetWebContents())
    return;
  Browser* browser = chrome::FindBrowserWithWebContents(
      web_ui()->GetWebContents());
  if (!browser || !browser->instant_controller())
    return;

  browser->instant_controller()->instant()->ClearDebugEvents();
#endif
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// InstantUI

InstantUI::InstantUI(content::WebUI* web_ui) : WebUIController(web_ui) {
  web_ui->AddMessageHandler(new InstantUIMessageHandler());

  // Set up the chrome://instant/ source.
  Profile* profile = Profile::FromWebUI(web_ui);
  content::WebUIDataSource::Add(profile, CreateInstantHTMLSource());
}

// static
void InstantUI::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterStringPref(
      prefs::kInstantUIZeroSuggestUrlPrefix,
      std::string(),
      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
