// Copyright 2018 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 "chromecast/base/metrics/cast_metrics_helper.h"

#include <string>

#include "base/json/json_reader.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "base/values.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::AllOf;
using ::testing::HasSubstr;
using ::testing::SaveArg;
using ::testing::_;

namespace chromecast {
namespace metrics {

namespace {

constexpr char kAppId1[] = "APP_ID_1";
constexpr char kAppId2[] = "APP_ID_2";
constexpr char kAppId3[] = "APP_ID_3";
constexpr char kEvent[] = "EVENT";
constexpr char kSdkVersion[] = "SDK_VERSION";
constexpr char kSessionId1[] = "SESSION_ID_1";
constexpr char kSessionId2[] = "SESSION_ID_2";
constexpr char kSessionId3[] = "SESSION_ID_3";
constexpr int kValue = 123;

constexpr base::TimeDelta kAppLoadTimeout = base::TimeDelta::FromMinutes(5);

MATCHER_P2(HasDouble, key, value, "") {
  auto v = base::JSONReader::ReadDeprecated(arg);
  return v && v->FindKey(key) && v->FindKey(key)->is_double() &&
         v->FindKey(key)->GetDouble() == value;
}

MATCHER_P2(HasInt, key, value, "") {
  auto v = base::JSONReader::ReadDeprecated(arg);
  return v && v->FindKey(key) && v->FindKey(key)->is_int() &&
         v->FindKey(key)->GetInt() == value;
}

MATCHER_P2(HasString, key, value, "") {
  auto v = base::JSONReader::ReadDeprecated(arg);
  return v && v->FindKey(key) && v->FindKey(key)->is_string() &&
         v->FindKey(key)->GetString() == value;
}

}  // namespace

class MockMetricsSink : public CastMetricsHelper::MetricsSink {
 public:
  MOCK_METHOD1(OnAction, void(const std::string&));
  MOCK_METHOD3(OnEnumerationEvent, void(const std::string&, int, int));
  MOCK_METHOD5(OnTimeEvent,
               void(const std::string&,
                    base::TimeDelta,
                    base::TimeDelta,
                    base::TimeDelta,
                    int));
};

class CastMetricsHelperTest : public ::testing::Test {
 public:
  CastMetricsHelperTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
        metrics_helper_(scoped_task_environment_.GetMainThreadTaskRunner(),
                        scoped_task_environment_.GetMockTickClock()) {
    metrics_helper_.SetMetricsSink(&metrics_sink_);
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  MockMetricsSink metrics_sink_;
  CastMetricsHelper metrics_helper_;
};

TEST_F(CastMetricsHelperTest, RecordEventWithValue) {
  const base::TimeDelta time = base::TimeDelta::FromSeconds(5);
  scoped_task_environment_.FastForwardBy(time);

  EXPECT_CALL(metrics_sink_,
              OnAction(AllOf(HasString("name", kEvent),
                             HasDouble("time", time.InMicroseconds()),
                             HasInt("value", kValue))));
  metrics_helper_.RecordApplicationEventWithValue(kEvent, kValue);
}

TEST_F(CastMetricsHelperTest, RecordApplicationEvent) {
  metrics_helper_.DidStartLoad(kAppId1);
  metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1);
  metrics_helper_.UpdateSDKInfo(kSdkVersion);

  const base::TimeDelta time = base::TimeDelta::FromSeconds(5);
  scoped_task_environment_.FastForwardBy(time);

  EXPECT_CALL(
      metrics_sink_,
      OnAction(AllOf(
          HasString("name", kEvent), HasDouble("time", time.InMicroseconds()),
          HasString("app_id", kAppId1), HasString("session_id", kSessionId1),
          HasString("sdk_version", kSdkVersion))));
  metrics_helper_.RecordApplicationEvent(kEvent);
}

TEST_F(CastMetricsHelperTest, RecordApplicationEventWithValue) {
  metrics_helper_.DidStartLoad(kAppId1);
  metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1);
  metrics_helper_.UpdateSDKInfo(kSdkVersion);

  const base::TimeDelta time = base::TimeDelta::FromSeconds(5);
  scoped_task_environment_.FastForwardBy(time);

  EXPECT_CALL(
      metrics_sink_,
      OnAction(AllOf(
          HasString("name", kEvent), HasDouble("time", time.InMicroseconds()),
          HasString("app_id", kAppId1), HasString("session_id", kSessionId1),
          HasString("sdk_version", kSdkVersion), HasInt("value", kValue))));
  metrics_helper_.RecordApplicationEventWithValue(kEvent, kValue);
}

TEST_F(CastMetricsHelperTest, LogTimeToFirstPaint) {
  metrics_helper_.DidStartLoad(kAppId1);
  metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1);

  const base::TimeDelta time_to_first_paint = base::TimeDelta::FromSeconds(5);
  scoped_task_environment_.FastForwardBy(time_to_first_paint);

  EXPECT_CALL(metrics_sink_, OnTimeEvent(AllOf(HasSubstr(kAppId1),
                                               HasSubstr("TimeToFirstPaint")),
                                         time_to_first_paint, _, _, _));
  metrics_helper_.LogTimeToFirstPaint();
}

TEST_F(CastMetricsHelperTest, LogTimeToFirstAudio) {
  metrics_helper_.DidStartLoad(kAppId1);
  metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1);

  const base::TimeDelta time_to_first_audio = base::TimeDelta::FromSeconds(5);
  scoped_task_environment_.FastForwardBy(time_to_first_audio);

  EXPECT_CALL(metrics_sink_, OnTimeEvent(AllOf(HasSubstr(kAppId1),
                                               HasSubstr("TimeToFirstAudio")),
                                         time_to_first_audio, _, _, _));
  metrics_helper_.LogTimeToFirstAudio();
}

TEST_F(CastMetricsHelperTest, MultipleApps) {
  metrics_helper_.DidStartLoad(kAppId1);
  scoped_task_environment_.FastForwardBy(kAppLoadTimeout);
  metrics_helper_.DidStartLoad(kAppId2);
  metrics_helper_.DidStartLoad(kAppId3);
  metrics_helper_.DidCompleteLoad(kAppId3, kSessionId3);
  // kAppId2 should become the current app.
  metrics_helper_.DidCompleteLoad(kAppId2, kSessionId2);
  // kAppId1 should not become the current app because it timed out.
  metrics_helper_.DidCompleteLoad(kAppId1, kSessionId1);

  EXPECT_CALL(metrics_sink_,
              OnAction(AllOf(HasString("app_id", kAppId2),
                             HasString("session_id", kSessionId2))));
  metrics_helper_.RecordApplicationEvent(kEvent);
}

}  // namespace metrics
}  // namespace chromecast
