// 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "net/http/http_status_code.h"
#include "remoting/base/chromoting_event.h"
#include "remoting/base/url_request.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

class FakeUrlRequest : public UrlRequest {
 public:
  FakeUrlRequest(const std::string& expected_post,
                 const UrlRequest::Result& returned_result)
      : expected_post_(expected_post), returned_result_(returned_result) {}

  void Respond() { on_result_callback_.Run(returned_result_); }

  // UrlRequest overrides.
  void SetPostData(const std::string& content_type,
                   const std::string& post_data) override {
    EXPECT_EQ(content_type, "application/json");
    EXPECT_EQ(post_data, expected_post_);
  }

  void AddHeader(const std::string& value) override {}

  void Start(const OnResultCallback& on_result_callback) override {
    on_result_callback_ = on_result_callback;
  }

 private:
  std::string expected_post_;
  UrlRequest::Result returned_result_;
  OnResultCallback on_result_callback_;

  DISALLOW_COPY_AND_ASSIGN(FakeUrlRequest);
};

class FakeUrlRequestFactory : public UrlRequestFactory {
 public:
  ~FakeUrlRequestFactory() override { EXPECT_TRUE(expected_requests_.empty()); }

  // Returns a respond closure. Run this closure to respond to the URL request.
  base::Closure AddExpectedRequest(const std::string& exp_post,
                                   const UrlRequest::Result& ret_result) {
    FakeUrlRequest* fakeRequest = new FakeUrlRequest(exp_post, ret_result);
    base::Closure closure =
        base::Bind(&FakeUrlRequest::Respond, base::Unretained(fakeRequest));
    expected_requests_.push_back(std::unique_ptr<UrlRequest>(fakeRequest));
    return closure;
  }

  // request_factory_ override.
  std::unique_ptr<UrlRequest> CreateUrlRequest(
      UrlRequest::Type type,
      const std::string& url,
      const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
    EXPECT_FALSE(expected_requests_.empty());
    if (expected_requests_.empty()) {
      return std::unique_ptr<UrlRequest>(nullptr);
    }
    EXPECT_EQ(type, UrlRequest::Type::POST);
    std::unique_ptr<UrlRequest> request(std::move(expected_requests_.front()));
    expected_requests_.pop_front();
    return request;
  }

 private:
  std::deque<std::unique_ptr<UrlRequest>> expected_requests_;
};

class TelemetryLogWriterTest : public testing::Test {
 public:
  TelemetryLogWriterTest()
      : request_factory_(new FakeUrlRequestFactory()),
        log_writer_("", base::WrapUnique(request_factory_)) {
    success_result_.success = true;
    success_result_.status = 200;
    success_result_.response_body = "{}";

    unauth_result_.success = false;
    unauth_result_.status = net::HTTP_UNAUTHORIZED;
    unauth_result_.response_body = "{}";
  }

 protected:
  void LogFakeEvent() {
    ChromotingEvent entry;
    entry.SetInteger("id", id_);
    id_++;
    log_writer_.Log(entry);
  }

  void SetAuthClosure() {
    log_writer_.SetAuthClosure(
        base::Bind(&TelemetryLogWriterTest::SetAuth, base::Unretained(this)));
  }

  UrlRequest::Result success_result_;
  UrlRequest::Result unauth_result_;

  FakeUrlRequestFactory* request_factory_;  // For peeking. No ownership.
  TelemetryLogWriter log_writer_;

  int set_auth_count_ = 0;

 private:
  void SetAuth() {
    set_auth_count_++;
    log_writer_.SetAuthToken("some token");
  }

  int id_ = 0;
};

// Test workflow: add request -> log event -> respond request.
// Test fails if req is incorrect or creates more/less reqs than expected
TEST_F(TelemetryLogWriterTest, PostOneLogImmediately) {
  auto respond = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", success_result_);
  LogFakeEvent();
  respond.Run();
}

TEST_F(TelemetryLogWriterTest, PostOneLogAndHaveTwoPendingLogs) {
  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", success_result_);
  LogFakeEvent();

  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":1},{\"id\":2}]}", success_result_);
  LogFakeEvent();
  LogFakeEvent();
  respond1.Run();
  respond2.Run();
}

TEST_F(TelemetryLogWriterTest, PostLogFailedAndRetry) {
  // kMaxTries = 5
  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  auto respond3 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  auto respond4 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  auto respond5 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());

  LogFakeEvent();

  respond1.Run();
  respond2.Run();
  respond3.Run();
  respond4.Run();
  respond5.Run();
}

TEST_F(TelemetryLogWriterTest, PostOneLogFailedResendWithTwoPendingLogs) {
  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  LogFakeEvent();

  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0},{\"id\":1},{\"id\":2}]}", success_result_);
  LogFakeEvent();
  LogFakeEvent();

  respond1.Run();
  respond2.Run();
}

TEST_F(TelemetryLogWriterTest, PostThreeLogsFailedAndResendWithOnePending) {
  // This tests the ordering of the resent log.
  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", UrlRequest::Result::Failed());
  LogFakeEvent();

  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0},{\"id\":1},{\"id\":2}]}",
      UrlRequest::Result::Failed());
  LogFakeEvent();
  LogFakeEvent();

  respond1.Run();

  auto respond3 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0},{\"id\":1},{\"id\":2},{\"id\":3}]}",
      success_result_);
  LogFakeEvent();

  respond2.Run();
  respond3.Run();
}

TEST_F(TelemetryLogWriterTest, PostOneUnauthorizedCallClosureAndRetry) {
  SetAuthClosure();

  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", unauth_result_);
  LogFakeEvent();

  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", success_result_);
  respond1.Run();
  respond2.Run();

  EXPECT_EQ(1, set_auth_count_);
}

TEST_F(TelemetryLogWriterTest, PostOneUnauthorizedAndJustRetry) {
  auto respond1 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", unauth_result_);
  LogFakeEvent();

  auto respond2 = request_factory_->AddExpectedRequest(
      "{\"event\":[{\"id\":0}]}", success_result_);
  respond1.Run();
  respond2.Run();

  EXPECT_EQ(0, set_auth_count_);
}

}  // namespace remoting
