// Copyright 2016 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 "remoting/base/telemetry_log_writer.h"

#include <array>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/containers/circular_deque.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/timer/timer.h"
#include "net/http/http_status_code.h"
#include "remoting/base/chromoting_event.h"
#include "remoting/base/fake_oauth_token_getter.h"
#include "remoting/base/protobuf_http_status.h"
#include "remoting/base/protobuf_http_test_responder.h"
#include "remoting/proto/remoting/v1/telemetry_messages.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

namespace {

MATCHER_P(HasDurations, durations, "") {
  apis::v1::CreateEventRequest request;
  EXPECT_TRUE(ProtobufHttpTestResponder::ParseRequestMessage(arg, &request));
  if (!request.has_payload() ||
      static_cast<std::size_t>(request.payload().events_size()) !=
          durations.size()) {
    return false;
  }
  for (std::size_t i = 0; i < durations.size(); ++i) {
    auto event = request.payload().events(i);
    if (!event.has_session_duration() ||
        event.session_duration() != durations[i]) {
      return false;
    }
  }
  return true;
}

template <typename... Args>
std::array<int, sizeof...(Args)> MakeIntArray(Args&&... args) {
  return {std::forward<Args>(args)...};
}

// Sets expectation for call to CreateEvent with the set of events specified,
// identified by their session_duration field. (Session duration is incremented
// after each call to LogFakeEvent.)
//
// responder: The ProtobufHttpTestResponder on which to set the expectation.
// durations: The durations of the expected events, grouped with parentheses.
//     E.g., (0) or (1, 2).
//
// Example usage:
//     EXPECT_EVENTS(test_responder_, (1, 2))
//         .WillOnce(DoSucceed(&test_responder_));
#define EXPECT_EVENTS(responder, durations)     \
  EXPECT_CALL((responder.GetMockInterceptor()), \
              Run(HasDurations(MakeIntArray durations)))

// Creates a success action to be passed to WillOnce and friends.
decltype(auto) DoSucceed(ProtobufHttpTestResponder* responder) {
  return [responder](const network::ResourceRequest& request) {
    return responder->AddResponse(request.url.spec(),
                                  apis::v1::CreateEventResponse());
  };
}

// Creates a failure action to be passed to WillOnce and friends.
decltype(auto) DoFail(ProtobufHttpTestResponder* responder) {
  return [responder](const network::ResourceRequest& request) {
    return responder->AddError(
        request.url.spec(),
        ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAVAILABLE,
                           "The service is unavailable."));
  };
}

}  // namespace

class TelemetryLogWriterTest : public testing::Test {
 public:
  TelemetryLogWriterTest() {
    log_writer_.Init(test_responder_.GetUrlLoaderFactory());
  }

  ~TelemetryLogWriterTest() override {
    // It's an async process to create request to send all pending events.
    RunUntilIdle();
  }

 protected:
  void LogFakeEvent() {
    ChromotingEvent entry;
    entry.SetInteger(ChromotingEvent::kSessionDurationKey, duration_);
    duration_++;
    log_writer_.Log(entry);
  }

  // Waits until TelemetryLog is idle.
  void RunUntilIdle() {
    // gRPC has its own event loop, which means sometimes the task queue will
    // be empty while gRPC is working. Thus, TaskEnvironment::RunUntilIdle can't
    // be used, as it would return early. Instead, TelemetryLogWriter is polled
    // to determine when it has finished.
    base::RunLoop run_loop;
    base::RepeatingTimer timer;
    // Mock clock will auto-fast-forward, so the delay here is somewhat
    // arbitrary.
    timer.Start(
        FROM_HERE, base::TimeDelta::FromSeconds(1),
        base::BindRepeating(
            [](TelemetryLogWriter* log_writer,
               base::RepeatingClosure quit_closure) {
              if (log_writer->IsIdleForTesting()) {
                quit_closure.Run();
              }
            },
            base::Unretained(&log_writer_), run_loop.QuitWhenIdleClosure()));
    run_loop.Run();
  }

  ProtobufHttpTestResponder test_responder_;
  TelemetryLogWriter log_writer_{
      std::make_unique<FakeOAuthTokenGetter>(OAuthTokenGetter::SUCCESS,
                                             "dummy",
                                             "dummy")};

 private:
  // Incremented for each event to allow them to be distinguished.
  int duration_ = 0;
  // MOCK_TIME will fast forward through back-off delays.
  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME};
};

TEST_F(TelemetryLogWriterTest, PostOneLogImmediately) {
  EXPECT_EVENTS(test_responder_, (0)).WillOnce(DoSucceed(&test_responder_));
  LogFakeEvent();
}

TEST_F(TelemetryLogWriterTest, PostOneLogAndHaveTwoPendingLogs) {
  ::testing::InSequence sequence;

  // First one is sent right away. Second two are batched and sent once the
  // first request has completed.
  EXPECT_EVENTS(test_responder_, (0)).WillOnce(DoSucceed(&test_responder_));
  EXPECT_EVENTS(test_responder_, (1, 2)).WillOnce(DoSucceed(&test_responder_));
  LogFakeEvent();
  LogFakeEvent();
  LogFakeEvent();
}

TEST_F(TelemetryLogWriterTest, PostLogFailedAndRetry) {
  EXPECT_EVENTS(test_responder_, (0))
      .Times(5)
      .WillRepeatedly(DoFail(&test_responder_));
  LogFakeEvent();
}

TEST_F(TelemetryLogWriterTest, PostOneLogFailedResendWithTwoPendingLogs) {
  EXPECT_EVENTS(test_responder_, (0)).WillOnce(DoFail(&test_responder_));
  EXPECT_EVENTS(test_responder_, (0, 1, 2))
      .WillOnce(DoSucceed(&test_responder_));
  LogFakeEvent();
  LogFakeEvent();
  LogFakeEvent();
}

TEST_F(TelemetryLogWriterTest, PostThreeLogsFailedAndResendWithOnePending) {
  // This tests the ordering of the resent log.
  EXPECT_EVENTS(test_responder_, (0)).WillOnce(DoFail(&test_responder_));
  EXPECT_EVENTS(test_responder_, (0, 1, 2))
      .WillOnce(testing::DoAll(
          testing::InvokeWithoutArgs([this]() { LogFakeEvent(); }),
          DoFail(&test_responder_)));
  EXPECT_EVENTS(test_responder_, (0, 1, 2, 3))
      .WillOnce(DoSucceed(&test_responder_));
  LogFakeEvent();
  LogFakeEvent();
  LogFakeEvent();
}

TEST_F(TelemetryLogWriterTest, PostOneFailedThenSucceed) {
  EXPECT_EVENTS(test_responder_, (0))
      .WillOnce(DoFail(&test_responder_))
      .WillOnce(DoSucceed(&test_responder_));
  LogFakeEvent();
}

}  // namespace remoting
