// Copyright 2015 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/media_router/media_router_webui_message_handler.h"

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/media/router/issue.h"
#include "chrome/browser/media/router/media_router_metrics.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/webui/media_router/media_cast_mode.h"
#include "chrome/browser/ui/webui/media_router/media_router_ui.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/web_ui.h"
#include "extensions/common/constants.h"
#include "ui/base/l10n/l10n_util.h"


namespace media_router {

namespace {

const char kCastLearnMorePageUrl[] =
    "https://www.google.com/chrome/devices/chromecast/learn.html";
const char kHelpPageUrlPrefix[] =
    "https://support.google.com/chromecast/answer/%d";

// Message names.
const char kRequestInitialData[] = "requestInitialData";
const char kCreateRoute[] = "requestRoute";
const char kAcknowledgeFirstRunFlow[] = "acknowledgeFirstRunFlow";
const char kActOnIssue[] = "actOnIssue";
const char kCloseRoute[] = "closeRoute";
const char kJoinRoute[] = "joinRoute";
const char kCloseDialog[] = "closeDialog";
const char kReportBlur[] = "reportBlur";
const char kReportClickedSinkIndex[] = "reportClickedSinkIndex";
const char kReportFilter[] = "reportFilter";
const char kReportInitialAction[] = "reportInitialAction";
const char kReportInitialState[] = "reportInitialState";
const char kReportNavigateToView[] = "reportNavigateToView";
const char kReportRouteCreationOutcome[] = "reportRouteCreationOutcome";
const char kReportRouteCreation[] = "reportRouteCreation";
const char kReportSelectedCastMode[] = "reportSelectedCastMode";
const char kReportSinkCount[] = "reportSinkCount";
const char kReportTimeToClickSink[] = "reportTimeToClickSink";
const char kReportTimeToInitialActionClose[] = "reportTimeToInitialActionClose";
const char kSearchSinksAndCreateRoute[] = "searchSinksAndCreateRoute";
const char kOnInitialDataReceived[] = "onInitialDataReceived";

// JS function names.
const char kSetInitialData[] = "media_router.ui.setInitialData";
const char kOnCreateRouteResponseReceived[] =
    "media_router.ui.onCreateRouteResponseReceived";
const char kReceiveSearchResult[] = "media_router.ui.receiveSearchResult";
const char kSetFirstRunFlowData[] = "media_router.ui.setFirstRunFlowData";
const char kSetIssue[] = "media_router.ui.setIssue";
const char kSetSinkListAndIdentity[] = "media_router.ui.setSinkListAndIdentity";
const char kSetRouteList[] = "media_router.ui.setRouteList";
const char kSetCastModeList[] = "media_router.ui.setCastModeList";
const char kUpdateMaxHeight[] = "media_router.ui.updateMaxHeight";
const char kWindowOpen[] = "window.open";

std::unique_ptr<base::DictionaryValue> SinksAndIdentityToValue(
    const std::vector<MediaSinkWithCastModes>& sinks,
    const AccountInfo& account_info) {
  std::unique_ptr<base::DictionaryValue> sink_list_and_identity(
      new base::DictionaryValue);
  bool show_email = false;
  bool show_domain = false;
  std::string user_domain;
  if (account_info.IsValid()) {
    user_domain = account_info.hosted_domain;
    sink_list_and_identity->SetString("userEmail", account_info.email);
  }

  std::unique_ptr<base::ListValue> sinks_val(new base::ListValue);

  for (const MediaSinkWithCastModes& sink_with_cast_modes : sinks) {
    std::unique_ptr<base::DictionaryValue> sink_val(new base::DictionaryValue);

    const MediaSink& sink = sink_with_cast_modes.sink;
    sink_val->SetString("id", sink.id());
    sink_val->SetString("name", sink.name());
    sink_val->SetInteger("iconType", sink.icon_type());
    if (sink.description())
      sink_val->SetString("description", *sink.description());

    bool is_pseudo_sink =
        base::StartsWith(sink.id(), "pseudo:", base::CompareCase::SENSITIVE);
    if (!user_domain.empty() && sink.domain() && !sink.domain()->empty()) {
      std::string domain = *sink.domain();
      // Convert default domains to user domain
      if (domain == "default") {
        domain = user_domain;
        if (domain == Profile::kNoHostedDomainFound) {
          // Default domain will be empty for non-dasher accounts.
          domain.clear();
        }
      }

      sink_val->SetString("domain", domain);

      show_email = show_email || !is_pseudo_sink;
      if (!domain.empty() && domain != user_domain) {
        show_domain = true;
      }
    }

    int cast_mode_bits = 0;
    for (MediaCastMode cast_mode : sink_with_cast_modes.cast_modes)
      cast_mode_bits |= cast_mode;

    sink_val->SetInteger("castModes", cast_mode_bits);
    sink_val->SetBoolean("isPseudoSink", is_pseudo_sink);
    sinks_val->Append(std::move(sink_val));
  }

  sink_list_and_identity->Set("sinks", sinks_val.release());
  sink_list_and_identity->SetBoolean("showEmail", show_email);
  sink_list_and_identity->SetBoolean("showDomain", show_domain);
  return sink_list_and_identity;
}

std::unique_ptr<base::DictionaryValue> RouteToValue(
    const MediaRoute& route,
    bool can_join,
    const std::string& extension_id,
    bool incognito,
    int current_cast_mode) {
  std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
  dictionary->SetString("id", route.media_route_id());
  dictionary->SetString("sinkId", route.media_sink_id());
  dictionary->SetString("description", route.description());
  dictionary->SetBoolean("isLocal", route.is_local());
  dictionary->SetBoolean("canJoin", can_join);
  if (current_cast_mode > 0) {
    dictionary->SetInteger("currentCastMode", current_cast_mode);
  }

  const std::string& custom_path = route.custom_controller_path();
  if (!incognito && !custom_path.empty()) {
    std::string full_custom_controller_path = base::StringPrintf("%s://%s/%s",
        extensions::kExtensionScheme, extension_id.c_str(),
            custom_path.c_str());
    DCHECK(GURL(full_custom_controller_path).is_valid());
    dictionary->SetString("customControllerPath",
                          full_custom_controller_path);
  }

  return dictionary;
}

std::unique_ptr<base::ListValue> CastModesToValue(
    const CastModeSet& cast_modes,
    const std::string& source_host) {
  std::unique_ptr<base::ListValue> value(new base::ListValue);

  for (const MediaCastMode& cast_mode : cast_modes) {
    std::unique_ptr<base::DictionaryValue> cast_mode_val(
        new base::DictionaryValue);
    cast_mode_val->SetInteger("type", cast_mode);
    cast_mode_val->SetString(
        "description", MediaCastModeToDescription(cast_mode, source_host));
    cast_mode_val->SetString("host", source_host);
    value->Append(std::move(cast_mode_val));
  }

  return value;
}

// Returns an Issue dictionary created from |issue| that can be used in WebUI.
std::unique_ptr<base::DictionaryValue> IssueToValue(const Issue& issue) {
  const IssueInfo& issue_info = issue.info();
  std::unique_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
  dictionary->SetInteger("id", issue.id());
  dictionary->SetString("title", issue_info.title);
  dictionary->SetString("message", issue_info.message);
  dictionary->SetInteger("defaultActionType",
                         static_cast<int>(issue_info.default_action));
  if (!issue_info.secondary_actions.empty()) {
    DCHECK_EQ(1u, issue_info.secondary_actions.size());
    dictionary->SetInteger("secondaryActionType",
                           static_cast<int>(issue_info.secondary_actions[0]));
  }
  if (!issue_info.route_id.empty())
    dictionary->SetString("routeId", issue_info.route_id);
  dictionary->SetBoolean("isBlocking", issue_info.is_blocking);
  if (issue_info.help_page_id > 0)
    dictionary->SetInteger("helpPageId", issue_info.help_page_id);

  return dictionary;
}

bool IsValidIssueActionTypeNum(int issue_action_type_num) {
  return issue_action_type_num >= 0 &&
         issue_action_type_num <=
             static_cast<int>(IssueInfo::Action::NUM_VALUES);
}

// Composes a "learn more" URL. The URL depends on template arguments in |args|.
// Returns an empty string if |args| is invalid.
std::string GetLearnMoreUrl(const base::DictionaryValue* args) {
  // TODO(imcheng): The template arguments for determining the learn more URL
  // should come from the Issue object in the browser, not from WebUI.
  int help_page_id = -1;
  if (!args->GetInteger("helpPageId", &help_page_id) || help_page_id < 0) {
    DVLOG(1) << "Invalid help page id.";
    return std::string();
  }

  std::string help_url = base::StringPrintf(kHelpPageUrlPrefix, help_page_id);
  if (!GURL(help_url).is_valid()) {
    DVLOG(1) << "Error: URL is invalid and cannot be opened.";
    return std::string();
  }
  return help_url;
}

}  // namespace

MediaRouterWebUIMessageHandler::MediaRouterWebUIMessageHandler(
    MediaRouterUI* media_router_ui)
    : incognito_(
          Profile::FromWebUI(media_router_ui->web_ui())->IsOffTheRecord()),
      dialog_closing_(false),
      media_router_ui_(media_router_ui) {}

MediaRouterWebUIMessageHandler::~MediaRouterWebUIMessageHandler() {
}

void MediaRouterWebUIMessageHandler::UpdateSinks(
    const std::vector<MediaSinkWithCastModes>& sinks) {
  DVLOG(2) << "UpdateSinks";
  std::unique_ptr<base::DictionaryValue> sinks_and_identity_val(
      SinksAndIdentityToValue(sinks, GetAccountInfo()));
  web_ui()->CallJavascriptFunctionUnsafe(kSetSinkListAndIdentity,
                                         *sinks_and_identity_val);
}

void MediaRouterWebUIMessageHandler::UpdateRoutes(
    const std::vector<MediaRoute>& routes,
    const std::vector<MediaRoute::Id>& joinable_route_ids,
    const std::unordered_map<MediaRoute::Id, MediaCastMode>&
        current_cast_modes) {
  std::unique_ptr<base::ListValue> routes_val(
      RoutesToValue(routes, joinable_route_ids, current_cast_modes));
  web_ui()->CallJavascriptFunctionUnsafe(kSetRouteList, *routes_val);
}

void MediaRouterWebUIMessageHandler::UpdateCastModes(
    const CastModeSet& cast_modes,
    const std::string& source_host) {
  DVLOG(2) << "UpdateCastModes";
  std::unique_ptr<base::ListValue> cast_modes_val(
      CastModesToValue(cast_modes, source_host));
  web_ui()->CallJavascriptFunctionUnsafe(kSetCastModeList, *cast_modes_val);
}

void MediaRouterWebUIMessageHandler::OnCreateRouteResponseReceived(
    const MediaSink::Id& sink_id,
    const MediaRoute* route) {
  DVLOG(2) << "OnCreateRouteResponseReceived";
  if (route) {
    int current_cast_mode = CurrentCastModeForRouteId(
        route->media_route_id(), media_router_ui_->routes_and_cast_modes());
    std::unique_ptr<base::DictionaryValue> route_value(RouteToValue(
        *route, false, media_router_ui_->GetRouteProviderExtensionId(),
        incognito_, current_cast_mode));
    web_ui()->CallJavascriptFunctionUnsafe(kOnCreateRouteResponseReceived,
                                           base::Value(sink_id), *route_value,
                                           base::Value(route->for_display()));
  } else {
    web_ui()->CallJavascriptFunctionUnsafe(kOnCreateRouteResponseReceived,
                                           base::Value(sink_id), base::Value(),
                                           base::Value(false));
  }
}

void MediaRouterWebUIMessageHandler::ReturnSearchResult(
    const std::string& sink_id) {
  DVLOG(2) << "ReturnSearchResult";
  web_ui()->CallJavascriptFunctionUnsafe(kReceiveSearchResult,
                                         base::Value(sink_id));
}

void MediaRouterWebUIMessageHandler::UpdateIssue(const Issue& issue) {
  DVLOG(2) << "UpdateIssue";
  web_ui()->CallJavascriptFunctionUnsafe(kSetIssue, *IssueToValue(issue));
}

void MediaRouterWebUIMessageHandler::ClearIssue() {
  DVLOG(2) << "ClearIssue";
  web_ui()->CallJavascriptFunctionUnsafe(kSetIssue, base::Value());
}

void MediaRouterWebUIMessageHandler::UpdateMaxDialogHeight(int height) {
  DVLOG(2) << "UpdateMaxDialogHeight";
  web_ui()->CallJavascriptFunctionUnsafe(kUpdateMaxHeight, base::Value(height));
}

void MediaRouterWebUIMessageHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      kRequestInitialData,
      base::Bind(&MediaRouterWebUIMessageHandler::OnRequestInitialData,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kCreateRoute,
      base::Bind(&MediaRouterWebUIMessageHandler::OnCreateRoute,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kAcknowledgeFirstRunFlow,
      base::Bind(&MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kActOnIssue,
      base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kCloseRoute,
      base::Bind(&MediaRouterWebUIMessageHandler::OnCloseRoute,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kJoinRoute,
      base::Bind(&MediaRouterWebUIMessageHandler::OnJoinRoute,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kCloseDialog,
      base::Bind(&MediaRouterWebUIMessageHandler::OnCloseDialog,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportBlur,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportBlur,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportClickedSinkIndex,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportClickedSinkIndex,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportFilter,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportFilter,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportInitialState,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportInitialState,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportInitialAction,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportInitialAction,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportRouteCreation,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportRouteCreation,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportRouteCreationOutcome,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportRouteCreationOutcome,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportSelectedCastMode,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportSelectedCastMode,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportNavigateToView,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportNavigateToView,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportSinkCount,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportSinkCount,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportTimeToClickSink,
      base::Bind(&MediaRouterWebUIMessageHandler::OnReportTimeToClickSink,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kReportTimeToInitialActionClose,
      base::Bind(
          &MediaRouterWebUIMessageHandler::OnReportTimeToInitialActionClose,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kSearchSinksAndCreateRoute,
      base::Bind(&MediaRouterWebUIMessageHandler::OnSearchSinksAndCreateRoute,
                 base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      kOnInitialDataReceived,
      base::Bind(&MediaRouterWebUIMessageHandler::OnInitialDataReceived,
                 base::Unretained(this)));
}

void MediaRouterWebUIMessageHandler::OnRequestInitialData(
    const base::ListValue* args) {
  DVLOG(1) << "OnRequestInitialData";
  media_router_ui_->OnUIInitiallyLoaded();
  base::DictionaryValue initial_data;

  // "No Cast devices found?" Chromecast help center page.
  initial_data.SetString("deviceMissingUrl",
      base::StringPrintf(kHelpPageUrlPrefix, 3249268));

  std::unique_ptr<base::DictionaryValue> sinks_and_identity(
      SinksAndIdentityToValue(media_router_ui_->sinks(), GetAccountInfo()));
  initial_data.Set("sinksAndIdentity", sinks_and_identity.release());

  std::unique_ptr<base::ListValue> routes(RoutesToValue(
      media_router_ui_->routes(), media_router_ui_->joinable_route_ids(),
      media_router_ui_->routes_and_cast_modes()));
  initial_data.Set("routes", routes.release());

  const std::set<MediaCastMode> cast_modes = media_router_ui_->cast_modes();
  std::unique_ptr<base::ListValue> cast_modes_list(CastModesToValue(
      cast_modes, media_router_ui_->GetPresentationRequestSourceName()));
  initial_data.Set("castModes", cast_modes_list.release());

  // If the cast mode last chosen for the current origin is tab mirroring,
  // that should be the cast mode initially selected in the dialog. Otherwise
  // the initial cast mode should be chosen automatically by the dialog.
  bool use_tab_mirroring =
      base::ContainsKey(cast_modes, MediaCastMode::TAB_MIRROR) &&
      media_router_ui_->UserSelectedTabMirroringForCurrentOrigin();
  initial_data.SetBoolean("useTabMirroring", use_tab_mirroring);

  web_ui()->CallJavascriptFunctionUnsafe(kSetInitialData, initial_data);
  media_router_ui_->UIInitialized();
}

void MediaRouterWebUIMessageHandler::OnCreateRoute(
    const base::ListValue* args) {
  DVLOG(1) << "OnCreateRoute";
  const base::DictionaryValue* args_dict = nullptr;
  std::string sink_id;
  int cast_mode_num = -1;
  if (!args->GetDictionary(0, &args_dict) ||
      !args_dict->GetString("sinkId", &sink_id) ||
      !args_dict->GetInteger("selectedCastMode", &cast_mode_num)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  if (sink_id.empty()) {
    DVLOG(1) << "Media Route UI did not respond with a "
             << "valid sink ID. Aborting.";
    return;
  }

  if (!IsValidCastModeNum(cast_mode_num)) {
    // TODO(imcheng): Record error condition with UMA.
    DVLOG(1) << "Invalid cast mode: " << cast_mode_num << ". Aborting.";
    return;
  }

  MediaRouterUI* media_router_ui =
      static_cast<MediaRouterUI*>(web_ui()->GetController());
  if (media_router_ui->HasPendingRouteRequest()) {
    DVLOG(1) << "UI already has pending route request. Ignoring.";
    IssueInfo issue(
        l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_PENDING_ROUTE),
        IssueInfo::Action::DISMISS, IssueInfo::Severity::NOTIFICATION);
    media_router_ui_->AddIssue(issue);
    return;
  }

  DVLOG(2) << __func__ << ": sink id: " << sink_id
           << ", cast mode: " << cast_mode_num;

  // TODO(haibinlu): Pass additional parameters into the CreateRoute request,
  // e.g. low-fps-mirror, user-override. (crbug.com/490364)
  if (!media_router_ui->CreateRoute(
          sink_id, static_cast<MediaCastMode>(cast_mode_num))) {
    DVLOG(1) << "Error initiating route request.";
  }
}

void MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow(
    const base::ListValue* args) {
  DVLOG(1) << "OnAcknowledgeFirstRunFlow";
  Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean(
      prefs::kMediaRouterFirstRunFlowAcknowledged, true);

  bool enabled_cloud_services = false;
  // Do not set the relevant cloud services prefs if the user was not shown
  // the cloud services prompt.
  if (!args->GetBoolean(0, &enabled_cloud_services)) {
    DVLOG(1) << "User was not shown the enable cloud services prompt.";
    return;
  }

  PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
  pref_service->SetBoolean(prefs::kMediaRouterEnableCloudServices,
                           enabled_cloud_services);
  pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, true);
}

void MediaRouterWebUIMessageHandler::OnActOnIssue(
    const base::ListValue* args) {
  DVLOG(1) << "OnActOnIssue";
  const base::DictionaryValue* args_dict = nullptr;
  Issue::Id issue_id;
  int action_type_num = -1;
  if (!args->GetDictionary(0, &args_dict) ||
      !args_dict->GetInteger("issueId", &issue_id) ||
      !args_dict->GetInteger("actionType", &action_type_num)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  if (!IsValidIssueActionTypeNum(action_type_num)) {
    DVLOG(1) << "Invalid action type: " << action_type_num;
    return;
  }
  IssueInfo::Action action_type =
      static_cast<IssueInfo::Action>(action_type_num);
  if (ActOnIssueType(action_type, args_dict))
    DVLOG(1) << "ActOnIssueType failed for Issue ID " << issue_id;
  media_router_ui_->ClearIssue(issue_id);
}

void MediaRouterWebUIMessageHandler::OnJoinRoute(const base::ListValue* args) {
  DVLOG(1) << "OnJoinRoute";
  const base::DictionaryValue* args_dict = nullptr;
  std::string route_id;
  std::string sink_id;
  if (!args->GetDictionary(0, &args_dict) ||
      !args_dict->GetString("sinkId", &sink_id) ||
      !args_dict->GetString("routeId", &route_id)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  if (sink_id.empty()) {
    DVLOG(1) << "Media Route UI did not respond with a "
             << "valid sink ID. Aborting.";
    return;
  }

  if (route_id.empty()) {
    DVLOG(1) << "Media Route UI did not respond with a "
             << "valid route ID. Aborting.";
    return;
  }

  MediaRouterUI* media_router_ui =
      static_cast<MediaRouterUI*>(web_ui()->GetController());
  if (media_router_ui->HasPendingRouteRequest()) {
    DVLOG(1) << "UI already has pending route request. Ignoring.";
    IssueInfo issue(
        l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_PENDING_ROUTE),
        IssueInfo::Action::DISMISS, IssueInfo::Severity::NOTIFICATION);
    media_router_ui_->AddIssue(issue);
    return;
  }

  if (!media_router_ui_->ConnectRoute(sink_id, route_id)) {
    DVLOG(1) << "Error initiating route join request.";
  }
}

void MediaRouterWebUIMessageHandler::OnCloseRoute(const base::ListValue* args) {
  DVLOG(1) << "OnCloseRoute";
  const base::DictionaryValue* args_dict = nullptr;
  std::string route_id;
  bool is_local = false;
  if (!args->GetDictionary(0, &args_dict) ||
      !args_dict->GetString("routeId", &route_id) ||
      !args_dict->GetBoolean("isLocal", &is_local)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  media_router_ui_->CloseRoute(route_id);
  UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StopRoute", !is_local);
}

void MediaRouterWebUIMessageHandler::OnCloseDialog(
    const base::ListValue* args) {
  DVLOG(1) << "OnCloseDialog";
  if (dialog_closing_)
    return;

  bool used_esc_to_close_dialog = false;
  if (!args->GetBoolean(0, &used_esc_to_close_dialog)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  if (used_esc_to_close_dialog) {
    base::RecordAction(base::UserMetricsAction(
        "MediaRouter_Ui_Dialog_ESCToClose"));
  }

  dialog_closing_ = true;
  media_router_ui_->Close();
}

void MediaRouterWebUIMessageHandler::OnReportBlur(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportBlur";
  base::RecordAction(base::UserMetricsAction("MediaRouter_Ui_Dialog_Blur"));
}

void MediaRouterWebUIMessageHandler::OnReportClickedSinkIndex(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportClickedSinkIndex";
  int index;
  if (!args->GetInteger(0, &index)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  UMA_HISTOGRAM_SPARSE_SLOWLY("MediaRouter.Ui.Action.StartLocalPosition",
                              std::min(index, 100));
}

void MediaRouterWebUIMessageHandler::OnReportFilter(const base::ListValue*) {
  DVLOG(1) << "OnReportFilter";
  base::RecordAction(base::UserMetricsAction("MediaRouter_Ui_Action_Filter"));
}

void MediaRouterWebUIMessageHandler::OnReportInitialAction(
  const base::ListValue* args) {
  DVLOG(1) << "OnReportInitialAction";
  int action;
  if (!args->GetInteger(0, &action)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  media_router::MediaRouterMetrics::RecordMediaRouterInitialUserAction(
      static_cast<MediaRouterUserAction>(action));
}

void MediaRouterWebUIMessageHandler::OnReportInitialState(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportInitialState";
  std::string initial_view;
  if (!args->GetString(0, &initial_view)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  bool sink_list_state = initial_view == "sink-list";
  DCHECK(sink_list_state || (initial_view == "route-details"));
  UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.InitialState", sink_list_state);
}

void MediaRouterWebUIMessageHandler::OnReportNavigateToView(
  const base::ListValue* args) {
  DVLOG(1) << "OnReportNavigateToView";
  std::string view;
  if (!args->GetString(0, &view)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  if (view == "cast-mode-list") {
    base::RecordAction(base::UserMetricsAction(
        "MediaRouter_Ui_Navigate_SinkListToSource"));
  } else if (view == "route-details") {
    base::RecordAction(base::UserMetricsAction(
        "MediaRouter_Ui_Navigate_SinkListToRouteDetails"));
  } else if (view == "sink-list") {
    base::RecordAction(base::UserMetricsAction(
        "MediaRouter_Ui_Navigate_RouteDetailsToSinkList"));
  }
}

void MediaRouterWebUIMessageHandler::OnReportRouteCreation(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportRouteCreation";
  bool route_created_successfully;
  if (!args->GetBoolean(0, &route_created_successfully)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful",
                        route_created_successfully);
}

void MediaRouterWebUIMessageHandler::OnReportRouteCreationOutcome(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportRouteCreationOutcome";
  int outcome;
  if (!args->GetInteger(0, &outcome)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }

  media_router::MediaRouterMetrics::RecordRouteCreationOutcome(
      static_cast<MediaRouterRouteCreationOutcome>(outcome));
}

void MediaRouterWebUIMessageHandler::OnReportSelectedCastMode(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportSelectedCastMode";
  int cast_mode_type;
  if (!args->GetInteger(0, &cast_mode_type)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  DCHECK(IsValidCastModeNum(cast_mode_type));
  UMA_HISTOGRAM_SPARSE_SLOWLY("MediaRouter.Ui.Navigate.SourceSelection",
                              cast_mode_type);
  media_router_ui_->RecordCastModeSelection(
      static_cast<MediaCastMode>(cast_mode_type));
}

void MediaRouterWebUIMessageHandler::OnReportSinkCount(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportSinkCount";
  int sink_count;
  if (!args->GetInteger(0, &sink_count)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  UMA_HISTOGRAM_COUNTS_100("MediaRouter.Ui.Device.Count", sink_count);
}

void MediaRouterWebUIMessageHandler::OnReportTimeToClickSink(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportTimeToClickSink";
  double time_to_click;
  if (!args->GetDouble(0, &time_to_click)) {
    DVLOG(1) << "Unable to extract args.";
    return;
  }
  UMA_HISTOGRAM_TIMES("MediaRouter.Ui.Action.StartLocal.Latency",
                      base::TimeDelta::FromMillisecondsD(time_to_click));
}

void MediaRouterWebUIMessageHandler::OnReportTimeToInitialActionClose(
    const base::ListValue* args) {
  DVLOG(1) << "OnReportTimeToInitialActionClose";
  double time_to_close;
  if (!args->GetDouble(0, &time_to_close)) {
    VLOG(0) << "Unable to extract args.";
    return;
  }
  UMA_HISTOGRAM_TIMES("MediaRouter.Ui.Action.CloseLatency",
                      base::TimeDelta::FromMillisecondsD(time_to_close));
}

void MediaRouterWebUIMessageHandler::OnSearchSinksAndCreateRoute(
    const base::ListValue* args) {
  DVLOG(1) << "OnSearchSinksAndCreateRoute";
  const base::DictionaryValue* args_dict = nullptr;
  std::string sink_id;
  std::string search_criteria;
  std::string domain;
  int cast_mode_num = -1;
  if (!args->GetDictionary(0, &args_dict) ||
      !args_dict->GetString("sinkId", &sink_id) ||
      !args_dict->GetString("searchCriteria", &search_criteria) ||
      !args_dict->GetString("domain", &domain) ||
      !args_dict->GetInteger("selectedCastMode", &cast_mode_num)) {
    DVLOG(1) << "Unable to extract args";
    return;
  }

  if (search_criteria.empty()) {
    DVLOG(1) << "Media Router UI did not provide valid search criteria. "
                "Aborting.";
    return;
  }

  if (!IsValidCastModeNum(cast_mode_num)) {
    DVLOG(1) << "Invalid cast mode: " << cast_mode_num << ". Aborting.";
    return;
  }

  media_router_ui_->SearchSinksAndCreateRoute(
      sink_id, search_criteria, domain,
      static_cast<MediaCastMode>(cast_mode_num));
}

void MediaRouterWebUIMessageHandler::OnInitialDataReceived(
    const base::ListValue* args) {
  DVLOG(1) << "OnInitialDataReceived";
  media_router_ui_->OnUIInitialDataReceived();
  MaybeUpdateFirstRunFlowData();
}

bool MediaRouterWebUIMessageHandler::ActOnIssueType(
    IssueInfo::Action action_type,
    const base::DictionaryValue* args) {
  if (action_type == IssueInfo::Action::LEARN_MORE) {
    std::string learn_more_url = GetLearnMoreUrl(args);
    if (learn_more_url.empty())
      return false;
    std::unique_ptr<base::ListValue> open_args(new base::ListValue);
    open_args->AppendString(learn_more_url);
    web_ui()->CallJavascriptFunctionUnsafe(kWindowOpen, *open_args);
    return true;
  } else {
    // Do nothing; no other issue action types require any other action.
    return true;
  }
}

void MediaRouterWebUIMessageHandler::MaybeUpdateFirstRunFlowData() {
  base::DictionaryValue first_run_flow_data;

  Profile* profile = Profile::FromWebUI(web_ui());
  PrefService* pref_service = profile->GetPrefs();

  bool first_run_flow_acknowledged =
      pref_service->GetBoolean(prefs::kMediaRouterFirstRunFlowAcknowledged);
  bool show_cloud_pref = false;
  // Cloud services preference is shown if user is logged in. If the user
  // enables sync after acknowledging the first run flow, this is treated as
  // the user opting into Google services, including cloud services, if the
  // browser is a Chrome branded build.
  if (!pref_service->GetBoolean(prefs::kMediaRouterCloudServicesPrefSet)) {
    SigninManagerBase* signin_manager =
        SigninManagerFactory::GetForProfile(profile);
    if (signin_manager && signin_manager->IsAuthenticated()) {
      // If the user had previously acknowledged the first run flow without
      // being shown the cloud services option, and is now logged in with sync
      // enabled, turn on cloud services.
      if (first_run_flow_acknowledged &&
          ProfileSyncServiceFactory::GetForProfile(profile)->IsSyncActive()) {
        pref_service->SetBoolean(prefs::kMediaRouterEnableCloudServices, true);
        pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet,
                                 true);
        // Return early since the first run flow won't be surfaced.
        return;
      }

      show_cloud_pref = true;
      // "Casting to a Hangout from Chrome" Chromecast help center page.
      first_run_flow_data.SetString("firstRunFlowCloudPrefLearnMoreUrl",
          base::StringPrintf(kHelpPageUrlPrefix, 6320939));
    }
  }

  // Return early if the first run flow won't be surfaced.
  if (first_run_flow_acknowledged && !show_cloud_pref)
    return;

  // General Chromecast learn more page.
  first_run_flow_data.SetString("firstRunFlowLearnMoreUrl",
                                kCastLearnMorePageUrl);
  first_run_flow_data.SetBoolean("wasFirstRunFlowAcknowledged",
                                 first_run_flow_acknowledged);
  first_run_flow_data.SetBoolean("showFirstRunFlowCloudPref", show_cloud_pref);
  web_ui()->CallJavascriptFunctionUnsafe(kSetFirstRunFlowData,
                                         first_run_flow_data);
}

AccountInfo MediaRouterWebUIMessageHandler::GetAccountInfo() {
  SigninManagerBase* signin_manager =
      SigninManagerFactory::GetForProfile(Profile::FromWebUI(web_ui()));
  return signin_manager ? signin_manager->GetAuthenticatedAccountInfo()
                        : AccountInfo();
}

int MediaRouterWebUIMessageHandler::CurrentCastModeForRouteId(
    const MediaRoute::Id& route_id,
    const std::unordered_map<MediaRoute::Id, MediaCastMode>& current_cast_modes)
    const {
  auto current_cast_mode_entry = current_cast_modes.find(route_id);
  int current_cast_mode = current_cast_mode_entry != current_cast_modes.end()
                              ? current_cast_mode_entry->second
                              : -1;
  return current_cast_mode;
}

std::unique_ptr<base::ListValue> MediaRouterWebUIMessageHandler::RoutesToValue(
    const std::vector<MediaRoute>& routes,
    const std::vector<MediaRoute::Id>& joinable_route_ids,
    const std::unordered_map<MediaRoute::Id, MediaCastMode>& current_cast_modes)
    const {
  std::unique_ptr<base::ListValue> value(new base::ListValue);
  const std::string& extension_id =
      media_router_ui_->GetRouteProviderExtensionId();

  for (const MediaRoute& route : routes) {
    bool can_join =
        base::ContainsValue(joinable_route_ids, route.media_route_id());
    int current_cast_mode = CurrentCastModeForRouteId(route.media_route_id(),
                                                      current_cast_modes);
    std::unique_ptr<base::DictionaryValue> route_val(RouteToValue(
        route, can_join, extension_id, incognito_, current_cast_mode));
    value->Append(std::move(route_val));
  }

  return value;
}

void MediaRouterWebUIMessageHandler::SetWebUIForTest(content::WebUI* web_ui) {
  set_web_ui(web_ui);
}

}  // namespace media_router
