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

#include <string>

// When testing the javacript code, it is cumbersome to have to keep
// re-building the resouces package and reloading the browser. To solve
// this, enable the following flag to read the webapp's source files
// directly off disk, so all you have to do is refresh the page to
// test the modifications.
// #define USE_SOURCE_FILES_DIRECTLY

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/tracked_objects.h"
#include "base/values.h"
#include "chrome/browser/metrics/tracking_synchronizer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_profiler/task_profiler_data_serializer.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.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"
#include "grit/generated_resources.h"

#ifdef USE_SOURCE_FILES_DIRECTLY
#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/path_service.h"
#endif  //  USE_SOURCE_FILES_DIRECTLY

using chrome_browser_metrics::TrackingSynchronizer;
using content::BrowserThread;
using content::WebContents;
using content::WebUIMessageHandler;

namespace {

#ifdef USE_SOURCE_FILES_DIRECTLY

class ProfilerWebUIDataSource : public content::URLDataSource {
 public:
  ProfilerWebUIDataSource() {
  }

 protected:
  // content::URLDataSource implementation.
  virtual std::string GetSource() OVERRIDE {
    return chrome::kChromeUIProfilerHost;
  }

  virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
    if (EndsWith(path, ".js", false))
      return "application/javascript";
    return "text/html";
  }

  virtual void StartDataRequest(
      const std::string& path,
      bool is_incognito,
      const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
    base::FilePath base_path;
    PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
    base_path = base_path.AppendASCII("chrome");
    base_path = base_path.AppendASCII("browser");
    base_path = base_path.AppendASCII("resources");
    base_path = base_path.AppendASCII("profiler");

    // If no resource was specified, default to profiler.html.
    std::string filename = path.empty() ? "profiler.html" : path;

    base::FilePath file_path;
    file_path = base_path.AppendASCII(filename);

    // Read the file synchronously and send it as the response.
    base::ThreadRestrictions::ScopedAllowIO allow;
    std::string file_contents;
    if (!base::ReadFileToString(file_path, &file_contents))
      LOG(ERROR) << "Couldn't read file: " << file_path.value();
    scoped_refptr<base::RefCountedString> response =
        new base::RefCountedString();
    response->data() = file_contents;
    callback.Run(response);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ProfilerWebUIDataSource);
};

#else  // USE_SOURCE_FILES_DIRECTLY

content::WebUIDataSource* CreateProfilerHTMLSource() {
  content::WebUIDataSource* source =
      content::WebUIDataSource::Create(chrome::kChromeUIProfilerHost);

  source->SetJsonPath("strings.js");
  source->AddResourcePath("profiler.js", IDR_PROFILER_JS);
  source->SetDefaultResource(IDR_PROFILER_HTML);
  return source;
}

#endif

// 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 ProfilerMessageHandler : public WebUIMessageHandler {
 public:
  ProfilerMessageHandler() {}

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

  // Messages.
  void OnGetData(const ListValue* list);
  void OnResetData(const ListValue* list);

 private:
  DISALLOW_COPY_AND_ASSIGN(ProfilerMessageHandler);
};

void ProfilerMessageHandler::RegisterMessages() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  web_ui()->RegisterMessageCallback("getData",
      base::Bind(&ProfilerMessageHandler::OnGetData, base::Unretained(this)));
  web_ui()->RegisterMessageCallback("resetData",
      base::Bind(&ProfilerMessageHandler::OnResetData,
                 base::Unretained(this)));
}

void ProfilerMessageHandler::OnGetData(const ListValue* list) {
  ProfilerUI* profiler_ui = static_cast<ProfilerUI*>(web_ui()->GetController());
  profiler_ui->GetData();
}

void ProfilerMessageHandler::OnResetData(const ListValue* list) {
  tracked_objects::ThreadData::ResetAllThreadData();
}

}  // namespace

ProfilerUI::ProfilerUI(content::WebUI* web_ui)
    : WebUIController(web_ui),
      weak_ptr_factory_(this) {
  web_ui->AddMessageHandler(new ProfilerMessageHandler());

  // Set up the chrome://profiler/ source.
  Profile* profile = Profile::FromWebUI(web_ui);
#if defined(USE_SOURCE_FILES_DIRECTLY)
  content::URLDataSource::Add(profile, new ProfilerWebUIDataSource);
#else
  content::WebUIDataSource::Add(profile, CreateProfilerHTMLSource());
#endif
}

ProfilerUI::~ProfilerUI() {
}

void ProfilerUI::GetData() {
  TrackingSynchronizer::FetchProfilerDataAsynchronously(
      weak_ptr_factory_.GetWeakPtr());
}

void ProfilerUI::ReceivedProfilerData(
    const tracked_objects::ProcessDataSnapshot& profiler_data,
    int process_type) {
  // Serialize the data to JSON.
  DictionaryValue json_data;
  task_profiler::TaskProfilerDataSerializer::ToValue(profiler_data,
                                                     process_type,
                                                     &json_data);

  // Send the data to the renderer.
  web_ui()->CallJavascriptFunction("g_browserBridge.receivedData", json_data);
}
