// Copyright (c) 2013 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 <stddef.h>
#include <stdint.h>

#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "media/base/media_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

using std::string;
namespace content {

struct SsrcEntry {
  string GetSsrcAttributeString() const {
    std::stringstream ss;
    ss << "a=ssrc:" << id;
    std::map<string, string>::const_iterator iter;
    for (iter = properties.begin(); iter != properties.end(); ++iter) {
      ss << " " << iter->first << ":" << iter->second;
    }
    return ss.str();
  }

  string GetAsJSON() const {
    std::stringstream ss;
    ss << "{";
    std::map<string, string>::const_iterator iter;
    for (iter = properties.begin(); iter != properties.end(); ++iter) {
      if (iter != properties.begin())
        ss << ",";
      ss << "\"" << iter->first << "\":\"" << iter->second << "\"";
    }
    ss << "}";
    return ss.str();
  }

  string id;
  std::map<string, string> properties;
};

struct EventEntry {
  string type;
  string value;
};

struct StatsUnit {
  string GetString() const {
    std::stringstream ss;
    ss << "{timestamp:" << timestamp << ", values:[";
    std::map<string, string>::const_iterator iter;
    for (iter = values.begin(); iter != values.end(); ++iter) {
      ss << "'" << iter->first << "','" << iter->second << "',";
    }
    ss << "]}";
    return ss.str();
  }

  int64_t timestamp;
  std::map<string, string> values;
};

struct StatsEntry {
  string type;
  string id;
  StatsUnit stats;
};

typedef std::map<string, std::vector<string> > StatsMap;

class PeerConnectionEntry {
 public:
  PeerConnectionEntry(int rid, int lid) : rid_(rid), lid_(lid) {}

  void AddEvent(const string& type, const string& value) {
    EventEntry entry = {type, value};
    events_.push_back(entry);
  }

  string getIdString() const {
    std::stringstream ss;
    ss << rid_ << "-" << lid_;
    return ss.str();
  }

  string getLogIdString() const {
    std::stringstream ss;
    ss << rid_ << "-" << lid_ << "-update-log";
    return ss.str();
  }

  string getAllUpdateString() const {
    std::stringstream ss;
    ss << "{rid:" << rid_ << ", lid:" << lid_ << ", log:[";
    for (size_t i = 0; i < events_.size(); ++i) {
      ss << "{type:'" << events_[i].type <<
          "', value:'" << events_[i].value << "'},";
    }
    ss << "]}";
    return ss.str();
  }

  int rid_;
  int lid_;
  std::vector<EventEntry> events_;
  // This is a record of the history of stats value reported for each stats
  // report id (e.g. ssrc-1234) for each stats name (e.g. framerate).
  // It a 2-D map with each map entry is a vector of reported values.
  // It is used to verify the graph data series.
  std::map<string, StatsMap> stats_;
};

class UserMediaRequestEntry {
 public:
  UserMediaRequestEntry(int rid,
                        int pid,
                        const std::string& origin,
                        const std::string& audio_constraints,
                        const std::string& video_constraints)
      : rid(rid),
        pid(pid),
        origin(origin),
        audio_constraints(audio_constraints),
        video_constraints(video_constraints) {}

  int rid;
  int pid;
  std::string origin;
  std::string audio_constraints;
  std::string video_constraints;
};

static const int64_t FAKE_TIME_STAMP = 3600000;

#if defined(OS_WIN)
// All tests are flaky on Windows: crbug.com/277322.
#define MAYBE_WebRtcInternalsBrowserTest DISABLED_WebRtcInternalsBrowserTest
#else
#define MAYBE_WebRtcInternalsBrowserTest WebRtcInternalsBrowserTest
#endif

class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
 public:
  MAYBE_WebRtcInternalsBrowserTest() {}
  ~MAYBE_WebRtcInternalsBrowserTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
  }

  void SetUpOnMainThread() override {
    ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kUseFakeDeviceForMediaStream));
  }

 protected:
  bool ExecuteJavascript(const string& javascript) {
    return ExecuteScript(shell(), javascript);
  }

  void ExpectTitle(const std::string& expected_title) const {
    std::u16string expected_title16(base::ASCIIToUTF16(expected_title));
    TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
    EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
  }

  // Execute the javascript of addPeerConnection.
  void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) {
    std::stringstream ss;
    ss << "{rid:" << pc.rid_ << ", lid:" << pc.lid_ << ", pid:" << 0 << ", "
       << "url:'u', rtcConfiguration:'s', constraints:'c'}";
    ASSERT_TRUE(ExecuteJavascript(
        "cr.webUIListenerCallback('add-peer-connection', " + ss.str() + ");"));
  }

  // Execute the javascript of removePeerConnection.
  void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) {
    std::stringstream ss;
    ss << "{rid:" << pc.rid_ << ", lid:" << pc.lid_ << "}";

    ASSERT_TRUE(ExecuteJavascript(
        "cr.webUIListenerCallback('remove-peer-connection', " + ss.str() +
        ");"));
  }

  // Execute the javascript of addGetUserMedia.
  void ExecuteAddGetUserMediaJs(const UserMediaRequestEntry& request) {
    std::stringstream ss;
    ss << "{rid:" << request.rid << ", pid:" << request.pid << ", origin:'"
       << request.origin << "', audio:'" << request.audio_constraints
       << "', video:'" << request.video_constraints << "'}";

    ASSERT_TRUE(ExecuteJavascript(
        "cr.webUIListenerCallback('add-get-user-media', " + ss.str() + ");"));
  }

  // Execute the javascript of removeGetUserMediaForRenderer.
  void ExecuteRemoveGetUserMediaForRendererJs(int rid) {
    std::stringstream ss;
    ss << "{rid:" << rid << "}";
    ASSERT_TRUE(ExecuteJavascript(
        "cr.webUIListenerCallback('remove-get-user-media-for-renderer', " +
        ss.str() + ");"));
  }

  // Verifies that the DOM element with id |id| exists.
  void VerifyElementWithId(const string& id) {
    bool result = false;
    ASSERT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send(document.getElementById('" + id +
            "') != null);",
        &result));
    EXPECT_TRUE(result);
  }

  // Verifies that the DOM element with id |id| does not exist.
  void VerifyNoElementWithId(const string& id) {
    bool result = false;
    ASSERT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send(document.getElementById('" + id +
            "') == null);",
        &result));
    EXPECT_TRUE(result);
  }

  // Verifies the JS Array of userMediaRequests matches |requests|.
  void VerifyUserMediaRequest(
      const std::vector<UserMediaRequestEntry>& requests) {
    string json_requests;
    ASSERT_TRUE(
        ExecuteScriptAndExtractString(shell(),
                                      "window.domAutomationController.send("
                                      "    JSON.stringify(userMediaRequests));",
                                      &json_requests));
    std::unique_ptr<base::Value> value_requests =
        base::JSONReader::ReadDeprecated(json_requests);

    EXPECT_EQ(base::Value::Type::LIST, value_requests->type());

    base::ListValue* list_request =
        static_cast<base::ListValue*>(value_requests.get());
    EXPECT_EQ(requests.size(), list_request->GetSize());

    for (size_t i = 0; i < requests.size(); ++i) {
      base::DictionaryValue* dict = nullptr;
      ASSERT_TRUE(list_request->GetDictionary(i, &dict));
      int rid, pid;
      std::string origin, audio, video;
      ASSERT_TRUE(dict->GetInteger("rid", &rid));
      ASSERT_TRUE(dict->GetInteger("pid", &pid));
      ASSERT_TRUE(dict->GetString("origin", &origin));
      ASSERT_TRUE(dict->GetString("audio", &audio));
      ASSERT_TRUE(dict->GetString("video", &video));
      EXPECT_EQ(requests[i].rid, rid);
      EXPECT_EQ(requests[i].pid, pid);
      EXPECT_EQ(requests[i].origin, origin);
      EXPECT_EQ(requests[i].audio_constraints, audio);
      EXPECT_EQ(requests[i].video_constraints, video);
    }

    bool user_media_tab_existed = false;
    ASSERT_TRUE(
        ExecuteScriptAndExtractBool(shell(),
                                    "window.domAutomationController.send("
                                    "    document.querySelector("
                                    "    '#user-media-tab-id') != null);",
                                    &user_media_tab_existed));
    EXPECT_EQ(!requests.empty(), user_media_tab_existed);

    if (user_media_tab_existed) {
      int user_media_request_count = -1;
      ASSERT_TRUE(ExecuteScriptAndExtractInt(
          shell(),
          "window.domAutomationController.send("
          "    document.querySelector('#user-media-tab-id')"
          "        .childNodes.length);",
          &user_media_request_count));
      ASSERT_EQ(requests.size(), static_cast<size_t>(user_media_request_count));
    }
  }

  // Verifies that DOM for |pc| is correctly created with the right content.
  void VerifyPeerConnectionEntry(const PeerConnectionEntry& pc) {
    VerifyElementWithId(pc.getIdString());
    if (pc.events_.size() == 0)
      return;

    string log_id = pc.getLogIdString();
    VerifyElementWithId(log_id);
    string result;
    for (size_t i = 0; i < pc.events_.size(); ++i) {
      std::stringstream ss;
      ss << "var row = document.getElementById('" << log_id << "').rows["
         << (i + 1)
         << "];"
            "var cell = row.lastChild;"
            "window.domAutomationController.send(cell.firstChild.textContent);";
      ASSERT_TRUE(ExecuteScriptAndExtractString(shell(), ss.str(), &result));
      EXPECT_EQ(pc.events_[i].type + pc.events_[i].value, result);
    }
  }

  // Executes the javascript of updatePeerConnection and verifies the result.
  void ExecuteAndVerifyUpdatePeerConnection(
      PeerConnectionEntry& pc, const string& type, const string& value) {
    pc.AddEvent(type, value);

    std::stringstream ss;
    ss << "{rid:" << pc.rid_ << ", lid:" << pc.lid_ << ", type:'" << type
       << "', value:'" << value << "'}";
    ASSERT_TRUE(ExecuteJavascript(
        "cr.webUIListenerCallback('update-peer-connection', " + ss.str() +
        ")"));

    VerifyPeerConnectionEntry(pc);
  }

  // Execute addStats and verifies that the stats table has the right content.
  void ExecuteAndVerifyAddStats(
      PeerConnectionEntry& pc, const string& type, const string& id,
      StatsUnit& stats) {
    StatsEntry entry = {type, id, stats};

    // Adds each new value to the map of stats history.
    std::map<string, string>::iterator iter;
    for (iter = stats.values.begin(); iter != stats.values.end(); iter++) {
      pc.stats_[id][iter->first].push_back(iter->second);
    }
    std::stringstream ss;
    ss << "(() => {\n";
    ss << "  setCurrentGetStatsMethod(OPTION_GETSTATS_LEGACY);\n";
    ss << "  cr.webUIListenerCallback('add-legacy-stats', "
       << "{rid:" << pc.rid_ << ", lid:" << pc.lid_ << ", reports:[{id:'" << id
       << "', type:'" << type << "', stats:" << stats.GetString() << "}]});\n";
    ss << "})()";
    ASSERT_TRUE(ExecuteJavascript(ss.str()));
    VerifyStatsTable(pc, entry);
  }


  // Verifies that the stats table has the right content.
  void VerifyStatsTable(const PeerConnectionEntry& pc,
                        const StatsEntry& report) {
    string table_id =
        pc.getIdString() + "-table-" + report.id;
    VerifyElementWithId(table_id);

    std::map<string, string>::const_iterator iter;
    for (iter = report.stats.values.begin();
         iter != report.stats.values.end(); iter++) {
      VerifyStatsTableRow(table_id, iter->first, iter->second);
    }
  }

  // Verifies that the row named as |name| of the stats table |table_id| has
  // the correct content as |name| : |value|.
  void VerifyStatsTableRow(const string& table_id,
                           const string& name,
                           const string& value) {
    VerifyElementWithId(table_id + "-" + name);

    string result;
    ASSERT_TRUE(ExecuteScriptAndExtractString(
        shell(),
        "var row = document.getElementById('" + table_id + "-" + name +
            "');"
            "var name = row.cells[0].textContent;"
            "var value = row.cells[1].textContent;"
            "window.domAutomationController.send(name + ':' + value)",
        &result));
    EXPECT_EQ(name + ":" + value, result);
  }

  // Verifies that the graph data series consistent with pc.stats_.
  void VerifyStatsGraph(const PeerConnectionEntry& pc) {
    std::map<string, StatsMap>::const_iterator stream_iter;
    for (stream_iter = pc.stats_.begin();
         stream_iter != pc.stats_.end(); stream_iter++) {
      StatsMap::const_iterator stats_iter;
      for (stats_iter = stream_iter->second.begin();
           stats_iter != stream_iter->second.end();
           stats_iter++) {
        string graph_id = stream_iter->first + "-" + stats_iter->first;
        for (size_t i = 0; i < stats_iter->second.size(); ++i) {
          float number;
          std::stringstream stream(stats_iter->second[i]);
          stream >> number;
          if (stream.fail())
            continue;
          VerifyGraphDataPoint(
              pc.getIdString(), graph_id, i, stats_iter->second[i]);
        }
      }
    }
  }

  // Verifies that the graph data point at index |index| has value |value|.
  void VerifyGraphDataPoint(const string& pc_id, const string& graph_id,
                            int index, const string& value) {
    bool result = false;
    ASSERT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send("
           "graphViews['" + pc_id + "-" + graph_id + "'] != null)",
        &result));
    EXPECT_TRUE(result);

    std::stringstream ss;
    ss << "var dp = peerConnectionDataStore['" << pc_id << "']"
          ".getDataSeries('" << graph_id << "').dataPoints_[" << index << "];"
          "window.domAutomationController.send(dp.value.toString())";
    string actual_value;
    ASSERT_TRUE(
        ExecuteScriptAndExtractString(shell(), ss.str(), &actual_value));
    EXPECT_EQ(value, actual_value);
  }

  // Get the JSON string of the ssrc info from the page.
  string GetSsrcInfo(const string& ssrc_id) {
    string result;
    EXPECT_TRUE(ExecuteScriptAndExtractString(
        shell(),
        "window.domAutomationController.send(JSON.stringify("
           "ssrcInfoManager.streamInfoContainer_['" + ssrc_id + "']))",
        &result));
    return result;
  }

  int GetSsrcInfoBlockCount(Shell* shell) {
    int count = 0;
    EXPECT_TRUE(ExecuteScriptAndExtractInt(
        shell,
        "window.domAutomationController.send("
        "    document.getElementsByClassName("
        "        ssrcInfoManager.SSRC_INFO_BLOCK_CLASS).length);",
        &count));
    return count;
  }

  // Verifies |dump| contains |peer_connection_number| peer connection dumps,
  // each containing |update_number| updates and |stats_number| stats tables.
  void VerifyPageDumpStructure(base::Value* dump,
                               int peer_connection_number,
                               int update_number,
                               int stats_number) {
    EXPECT_NE((base::Value*)nullptr, dump);
    EXPECT_EQ(base::Value::Type::DICTIONARY, dump->type());

    base::DictionaryValue* dict_dump =
        static_cast<base::DictionaryValue*>(dump);
    EXPECT_EQ((size_t) peer_connection_number, dict_dump->size());

    base::DictionaryValue::Iterator it(*dict_dump);
    for (; !it.IsAtEnd(); it.Advance()) {
      base::Value* value = nullptr;
      dict_dump->Get(it.key(), &value);
      EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());
      base::DictionaryValue* pc_dump =
          static_cast<base::DictionaryValue*>(value);
      EXPECT_TRUE(pc_dump->HasKey("updateLog"));
      EXPECT_TRUE(pc_dump->HasKey("stats"));

      // Verifies the number of updates.
      pc_dump->Get("updateLog", &value);
      EXPECT_EQ(base::Value::Type::LIST, value->type());
      base::ListValue* list = static_cast<base::ListValue*>(value);
      EXPECT_EQ((size_t) update_number, list->GetSize());

      // Verifies the number of stats tables.
      pc_dump->Get("stats", &value);
      EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());
      base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(value);
      EXPECT_EQ((size_t) stats_number, dict->size());
    }
  }

  // Verifies |dump| contains the correct statsTable and statsDataSeries for
  // |pc|.
  void VerifyStatsDump(base::Value* dump,
                       const PeerConnectionEntry& pc,
                       const string& report_type,
                       const string& report_id,
                       const StatsUnit& stats) {
    EXPECT_NE((base::Value*)nullptr, dump);
    EXPECT_EQ(base::Value::Type::DICTIONARY, dump->type());

    base::DictionaryValue* dict_dump =
        static_cast<base::DictionaryValue*>(dump);
    base::Value* value = nullptr;
    dict_dump->Get(pc.getIdString(), &value);
    base::DictionaryValue* pc_dump = static_cast<base::DictionaryValue*>(value);

    // Verifies there is one data series per stats name.
    value = nullptr;
    pc_dump->Get("stats", &value);
    EXPECT_EQ(base::Value::Type::DICTIONARY, value->type());

    base::DictionaryValue* dataSeries =
        static_cast<base::DictionaryValue*>(value);
    EXPECT_EQ(stats.values.size(), dataSeries->size());
  }
};

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
                       AddAndRemovePeerConnection) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // Add two PeerConnections and then remove them.
  PeerConnectionEntry pc_1(1, 0);
  ExecuteAddPeerConnectionJs(pc_1);
  VerifyPeerConnectionEntry(pc_1);

  PeerConnectionEntry pc_2(2, 1);
  ExecuteAddPeerConnectionJs(pc_2);
  VerifyPeerConnectionEntry(pc_2);

  ExecuteRemovePeerConnectionJs(pc_1);
  VerifyNoElementWithId(pc_1.getIdString());
  VerifyPeerConnectionEntry(pc_2);

  ExecuteRemovePeerConnectionJs(pc_2);
  VerifyNoElementWithId(pc_2.getIdString());
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
                       UpdateAllPeerConnections) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc_0(1, 0);
  pc_0.AddEvent("e1", "v1");
  pc_0.AddEvent("e2", "v2");
  PeerConnectionEntry pc_1(1, 1);
  pc_1.AddEvent("e3", "v3");
  pc_1.AddEvent("e4", "v4");
  string pc_array = "[" + pc_0.getAllUpdateString() + ", " +
                          pc_1.getAllUpdateString() + "]";
  EXPECT_TRUE(ExecuteJavascript(
      "cr.webUIListenerCallback('update-all-peer-connections', " + pc_array +
      ");"));
  VerifyPeerConnectionEntry(pc_0);
  VerifyPeerConnectionEntry(pc_1);
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, UpdatePeerConnection) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // Add one PeerConnection and send one update.
  PeerConnectionEntry pc_1(1, 0);
  ExecuteAddPeerConnectionJs(pc_1);

  ExecuteAndVerifyUpdatePeerConnection(pc_1, "e1", "v1");

  // Add another PeerConnection and send two updates.
  PeerConnectionEntry pc_2(1, 1);
  ExecuteAddPeerConnectionJs(pc_2);

  SsrcEntry ssrc1, ssrc2;
  ssrc1.id = "ssrcid1";
  ssrc1.properties["msid"] = "mymsid";
  ssrc2.id = "ssrcid2";
  ssrc2.properties["label"] = "mylabel";
  ssrc2.properties["cname"] = "mycname";

  ExecuteAndVerifyUpdatePeerConnection(pc_2, "setRemoteDescription",
      ssrc1.GetSsrcAttributeString());

  ExecuteAndVerifyUpdatePeerConnection(pc_2, "createAnswerOnSuccess",
                                       ssrc2.GetSsrcAttributeString());
  ExecuteAndVerifyUpdatePeerConnection(pc_2, "setLocalDescription",
      ssrc2.GetSsrcAttributeString());

  EXPECT_EQ(ssrc1.GetAsJSON(), GetSsrcInfo(ssrc1.id));
  EXPECT_EQ(ssrc2.GetAsJSON(), GetSsrcInfo(ssrc2.id));

  StatsUnit stats = {FAKE_TIME_STAMP};
  stats.values["ssrc"] = ssrc1.id;
  ExecuteAndVerifyAddStats(pc_2, "ssrc", "dummyId", stats);
  EXPECT_GT(GetSsrcInfoBlockCount(shell()), 0);
}

// Tests that adding random named stats updates the dataSeries and graphs.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, AddStats) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc(1, 0);
  ExecuteAddPeerConnectionJs(pc);

  const string type = "ssrc";
  const string id = "ssrc-1234";
  StatsUnit stats = {FAKE_TIME_STAMP};
  stats.values["trackId"] = "abcd";
  stats.values["bitrate"] = "2000";
  stats.values["framerate"] = "30";

  // Add new stats and verify the stats table and graphs.
  ExecuteAndVerifyAddStats(pc, type, id, stats);
  VerifyStatsGraph(pc);

  // Update existing stats and verify the stats table and graphs.
  stats.values["bitrate"] = "2001";
  stats.values["framerate"] = "31";
  ExecuteAndVerifyAddStats(pc, type, id, stats);
  VerifyStatsGraph(pc);
}

// Tests that the bandwidth estimation values are drawn on a single graph.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, BweCompoundGraph) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc(1, 0);
  ExecuteAddPeerConnectionJs(pc);

  StatsUnit stats = {FAKE_TIME_STAMP};
  stats.values["googAvailableSendBandwidth"] = "1000000";
  stats.values["googTargetEncBitrate"] = "1000";
  stats.values["googActualEncBitrate"] = "1000000";
  stats.values["googRetransmitBitrate"] = "10";
  stats.values["googTransmitBitrate"] = "1000000";
  const string stats_type = "bwe";
  const string stats_id = "videobwe";
  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);

  string graph_id =
      pc.getIdString() + "-" + stats_id + "-bweCompound";
  bool result = false;
  // Verify that the bweCompound graph exists.
  ASSERT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send("
        "   graphViews['" + graph_id + "'] != null)",
        &result));
  EXPECT_TRUE(result);

  // Verify that the bweCompound graph contains multiple dataSeries.
  int count = 0;
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
        shell(),
        "window.domAutomationController.send("
        "   graphViews['" + graph_id + "'].getDataSeriesCount())",
        &count));
  EXPECT_EQ((int)stats.values.size(), count);
}

// Tests that the total packet/byte count is converted to count per second,
// and the converted data is drawn.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, ConvertedGraphs) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc(1, 0);
  ExecuteAddPeerConnectionJs(pc);

  const string stats_type = "s";
  const string stats_id = "1";
  const int num_converted_stats = 4;
  const string stats_names[] =
      {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"};
  const string converted_names[] =
      {"packetsSentPerSecond", "bitsSentPerSecond",
       "packetsReceivedPerSecond", "bitsReceivedPerSecond"};
  const string first_value = "1000";
  const string second_value = "2000";
  const string converted_values[] = {"1000", "8000", "1000", "8000"};

  // Send the first data point.
  StatsUnit stats = {FAKE_TIME_STAMP};
  for (int i = 0; i < num_converted_stats; ++i)
    stats.values[stats_names[i]] = first_value;

  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);

  // Send the second data point at 1000ms after the first data point.
  stats.timestamp += 1000;
  for (int i = 0; i < num_converted_stats; ++i)
    stats.values[stats_names[i]] = second_value;
  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);

  // Verifies the graph data matches converted_values.
  for (int i = 0; i < num_converted_stats; ++i) {
    VerifyGraphDataPoint(pc.getIdString(), stats_id + "-" + converted_names[i],
                         1, converted_values[i]);
  }
}

// Timing out on ARM linux bot: http://crbug.com/238490
// Disabling due to failure on Linux, Mac, Win: http://crbug.com/272413
// Sanity check of the page content under a real PeerConnection call.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
                       DISABLED_WithRealPeerConnectionCall) {
  // Start a peerconnection call in the first window.
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
  ExpectTitle("OK");

  // Open webrtc-internals in the second window.
  GURL url2("chrome://webrtc-internals");
  Shell* shell2 = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(shell2, url2));

  const int NUMBER_OF_PEER_CONNECTIONS = 2;

  // Verifies the number of peerconnections.
  int count = 0;
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell2,
      "window.domAutomationController.send("
      "    document.querySelector('#peer-connections-list')"
      "        .getElementsByTagName('li').length);",
      &count));
  EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);

  // Verifies the the event tables.
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell2,
      "window.domAutomationController.send("
      "    document.querySelector('#peer-connections-list')"
      "        .getElementsByClassName('update-log-table').length);",
      &count));
  EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);

  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell2,
      "window.domAutomationController.send("
      "    document.querySelector('#peer-connections-list')"
      "        .getElementsByClassName('update-log-table')[0].rows.length);",
      &count));
  EXPECT_GT(count, 1);

  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell2,
      "window.domAutomationController.send("
      "    document.querySelector('#peer-connections-list')"
      "        .getElementsByClassName('update-log-table')[1].rows.length);",
      &count));
  EXPECT_GT(count, 1);

  // Wait until the stats table containers are created.
  count = 0;
  while (count != NUMBER_OF_PEER_CONNECTIONS) {
    ASSERT_TRUE(ExecuteScriptAndExtractInt(
        shell2,
        "window.domAutomationController.send("
        "    document.querySelector('#peer-connections-list')"
        "        .getElementsByClassName("
        "        'stats-table-container').length);",
        &count));
  }

  // Verifies each stats table having more than one rows.
  bool result = false;
  ASSERT_TRUE(ExecuteScriptAndExtractBool(
      shell2,
      "var tableContainers = document.querySelector('#peer-connections-list')"
      "    .getElementsByClassName('stats-table-container');"
      "var result = true;"
      "for (var i = 0; i < tableContainers.length && result; ++i) {"
      "  var tables = tableContainers[i].getElementsByTagName('table');"
      "  for (var j = 0; j < tables.length && result; ++j) {"
      "    result = (tables[j].rows.length > 1);"
      "  }"
      "  if (!result) {"
      "    console.log(tableContainers[i].innerHTML);"
      "  }"
      "}"
      "window.domAutomationController.send(result);",
      &result));

  EXPECT_TRUE(result);

  count = GetSsrcInfoBlockCount(shell2);
  EXPECT_GT(count, 0);
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, CreatePageDump) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc_0(1, 0);
  pc_0.AddEvent("e1", "v1");
  pc_0.AddEvent("e2", "v2");
  PeerConnectionEntry pc_1(1, 1);
  pc_1.AddEvent("e3", "v3");
  pc_1.AddEvent("e4", "v4");
  string pc_array =
      "[" + pc_0.getAllUpdateString() + ", " + pc_1.getAllUpdateString() + "]";
  EXPECT_TRUE(ExecuteJavascript(
      "cr.webUIListenerCallback('update-all-peer-connections', " + pc_array +
      ");"));

  // Verifies the peer connection data store can be created without stats.
  string dump_json;
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      shell(),
      "window.domAutomationController.send("
      "    JSON.stringify(peerConnectionDataStore));",
      &dump_json));
  std::unique_ptr<base::Value> dump =
      base::JSONReader::ReadDeprecated(dump_json);
  VerifyPageDumpStructure(dump.get(),
                          2 /*peer_connection_number*/,
                          2 /*update_number*/,
                          0 /*stats_number*/);

  // Adds a stats report.
  const string type = "dummy";
  const string id = "1234";
  StatsUnit stats = { FAKE_TIME_STAMP };
  stats.values["bitrate"] = "2000";
  stats.values["framerate"] = "30";
  ExecuteAndVerifyAddStats(pc_0, type, id, stats);

  ASSERT_TRUE(ExecuteScriptAndExtractString(
      shell(),
      "window.domAutomationController.send("
      "    JSON.stringify(peerConnectionDataStore));",
      &dump_json));
  dump = base::JSONReader::ReadDeprecated(dump_json);
  VerifyStatsDump(dump.get(), pc_0, type, id, stats);
}

IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, UpdateGetUserMedia) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  UserMediaRequestEntry request1(1, 1, "origin", "ac", "vc");
  UserMediaRequestEntry request2(2, 2, "origin2", "ac2", "vc2");
  ExecuteAddGetUserMediaJs(request1);
  ExecuteAddGetUserMediaJs(request2);

  std::vector<UserMediaRequestEntry> list;
  list.push_back(request1);
  list.push_back(request2);
  VerifyUserMediaRequest(list);

  ExecuteRemoveGetUserMediaForRendererJs(1);
  list.erase(list.begin());
  VerifyUserMediaRequest(list);

  ExecuteRemoveGetUserMediaForRendererJs(2);
  list.erase(list.begin());
  VerifyUserMediaRequest(list);
}

// Tests that the received propagation delta values are converted and drawn
// correctly.
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
                       ReceivedPropagationDelta) {
  GURL url("chrome://webrtc-internals");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  PeerConnectionEntry pc(1, 0);
  ExecuteAddPeerConnectionJs(pc);

  StatsUnit stats = {FAKE_TIME_STAMP};
  stats.values["googReceivedPacketGroupArrivalTimeDebug"] =
      "[1000, 1100, 1200]";
  stats.values["googReceivedPacketGroupPropagationDeltaDebug"] =
      "[10, 20, 30]";
  const string stats_type = "bwe";
  const string stats_id = "videobwe";
  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);

  string graph_id = pc.getIdString() + "-" + stats_id +
      "-googReceivedPacketGroupPropagationDeltaDebug";
  string data_series_id =
      stats_id + "-googReceivedPacketGroupPropagationDeltaDebug";
  bool result = false;
  // Verify that the graph exists.
  ASSERT_TRUE(ExecuteScriptAndExtractBool(
      shell(),
      "window.domAutomationController.send("
      "   graphViews['" + graph_id + "'] != null)",
      &result));
  EXPECT_TRUE(result);

  // Verify that the graph contains multiple data points.
  int count = 0;
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell(),
      "window.domAutomationController.send("
      "   graphViews['" + graph_id + "'].getDataSeriesCount())",
      &count));
  EXPECT_EQ(1, count);
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      shell(),
      "window.domAutomationController.send("
      "   peerConnectionDataStore['" + pc.getIdString() + "']" +
      "       .getDataSeries('" + data_series_id + "').getCount())",
      &count));
  EXPECT_EQ(3, count);
}

}  // namespace content
