// 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 "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/ntp_snippets/ntp_snippet.h"
#include "components/ntp_snippets/ntp_snippets_fetcher.h"
#include "components/ntp_snippets/ntp_snippets_service.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ntp_snippets {

class SnippetObserver : public NTPSnippetsServiceObserver {
 public:
  SnippetObserver() : loaded_(false), shutdown_(false) {}
  ~SnippetObserver() override {}

  void NTPSnippetsServiceLoaded(NTPSnippetsService* service) override {
    loaded_ = true;
  }

  void NTPSnippetsServiceShutdown(NTPSnippetsService* service) override {
    shutdown_ = true;
    loaded_ = false;
  }

  bool loaded_;
  bool shutdown_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SnippetObserver);
};

class NTPSnippetsServiceTest : public testing::Test {
 public:
  NTPSnippetsServiceTest() {}
  ~NTPSnippetsServiceTest() override {}

  void SetUp() override {
    signin_client_.reset(new TestSigninClient(nullptr));
    account_tracker_.reset(new AccountTrackerService());
  }

 protected:
  scoped_ptr<NTPSnippetsService> CreateSnippetService() {
    scoped_refptr<base::SingleThreadTaskRunner> task_runner(
        base::ThreadTaskRunnerHandle::Get());
    scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
        new net::TestURLRequestContextGetter(task_runner.get());
    FakeProfileOAuth2TokenService* token_service =
        new FakeProfileOAuth2TokenService();
    FakeSigninManagerBase* signin_manager =  new FakeSigninManagerBase(
        signin_client_.get(), account_tracker_.get());

    scoped_ptr<NTPSnippetsService> service(new NTPSnippetsService(
        nullptr, nullptr, task_runner.get(), std::string("fr"), nullptr,
        make_scoped_ptr(new NTPSnippetsFetcher(
            task_runner.get(), signin_manager, token_service,
            request_context_getter, base::FilePath()))));
    return service;
  }

 private:
  scoped_ptr<AccountTrackerService> account_tracker_;
  scoped_ptr<TestSigninClient> signin_client_;
  base::MessageLoop message_loop_;
  DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest);
};

std::string GetTestJson(const std::string& content_creation_time_str,
                        const std::string& expiry_time_str) {
  char json_str_format[] =
      "{ \"recos\": [ "
      "{ \"contentInfo\": {"
      "\"url\" : \"http://localhost/foobar\","
      "\"site_title\" : \"Site Title\","
      "\"favicon_url\" : \"http://localhost/favicon\","
      "\"title\" : \"Title\","
      "\"snippet\" : \"Snippet\","
      "\"thumbnailUrl\" : \"http://localhost/salient_image\","
      "\"creationTimestampSec\" : \"%s\","
      "\"expiryTimestampSec\" : \"%s\""
      "}}"
      "]}";

  return base::StringPrintf(json_str_format, content_creation_time_str.c_str(),
                            expiry_time_str.c_str());
}

std::string GetTestJson(const std::string& content_creation_time_str) {
  int64_t expiry_time =
      (base::Time::Now() + base::TimeDelta::FromHours(1)).ToJavaTime() /
      base::Time::kMillisecondsPerSecond;

  return GetTestJson(content_creation_time_str,
                     base::Int64ToString(expiry_time));
}

std::string GetTestJson(int64_t content_creation_time_sec) {
  int64_t expiry_time =
      (base::Time::Now() + base::TimeDelta::FromHours(1)).ToJavaTime() /
      base::Time::kMillisecondsPerSecond;

  return GetTestJson(base::Int64ToString(content_creation_time_sec),
                     base::Int64ToString(expiry_time));
}

std::string GetTestExpiredJson(int64_t content_creation_time_sec) {
  int64_t expiry_time =
      (base::Time::Now()).ToJavaTime() / base::Time::kMillisecondsPerSecond;

  return GetTestJson(base::Int64ToString(content_creation_time_sec),
                     base::Int64ToString(expiry_time));
}

TEST_F(NTPSnippetsServiceTest, Create) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());
  EXPECT_FALSE(service->is_loaded());
}

TEST_F(NTPSnippetsServiceTest, Loop) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  EXPECT_FALSE(service->is_loaded());

  std::string json_str(
      "{ \"recos\": [ "
      "{ \"contentInfo\": { \"url\" : \"http://localhost/foobar\" }}"
      "]}");
  EXPECT_TRUE(service->LoadFromJSONString(json_str));

  EXPECT_TRUE(service->is_loaded());

  // The same for loop without the '&' should not compile.
  for (auto& snippet : *service) {
    // Snippet here is a const.
    EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar"));
  }
  // Without the const, this should not compile.
  for (const NTPSnippet& snippet : *service) {
    EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar"));
  }
}

TEST_F(NTPSnippetsServiceTest, Full) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  std::string json_str(GetTestJson(1448459205));

  EXPECT_TRUE(service->LoadFromJSONString(json_str));
  EXPECT_EQ(service->size(), 1u);

  // The same for loop without the '&' should not compile.
  for (auto& snippet : *service) {
    // Snippet here is a const.
    EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar"));
    EXPECT_EQ(snippet.site_title(), "Site Title");
    EXPECT_EQ(snippet.favicon_url(), GURL("http://localhost/favicon"));
    EXPECT_EQ(snippet.title(), "Title");
    EXPECT_EQ(snippet.snippet(), "Snippet");
    EXPECT_EQ(snippet.salient_image_url(),
              GURL("http://localhost/salient_image"));
    base::Time then =
        base::Time::FromUTCExploded({2015, 11, 4, 25, 13, 46, 45});
    EXPECT_EQ(then, snippet.publish_date());
  }
}

TEST_F(NTPSnippetsServiceTest, CreationTimestampParseFail) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  std::string json_str(GetTestJson("aaa1448459205"));

  EXPECT_TRUE(service->LoadFromJSONString(json_str));
  EXPECT_EQ(service->size(), 1u);

  // The same for loop without the '&' should not compile.
  for (auto& snippet : *service) {
    // Snippet here is a const.
    EXPECT_EQ(snippet.url(), GURL("http://localhost/foobar"));
    EXPECT_EQ(snippet.title(), "Title");
    EXPECT_EQ(snippet.snippet(), "Snippet");
    EXPECT_EQ(base::Time::UnixEpoch(), snippet.publish_date());
  }
}

TEST_F(NTPSnippetsServiceTest, RemoveExpiredContent) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  std::string json_str(GetTestExpiredJson(1448459205));

  EXPECT_TRUE(service->LoadFromJSONString(json_str));
  EXPECT_EQ(service->size(), 0u);
}

TEST_F(NTPSnippetsServiceTest, ObserverNotLoaded) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  SnippetObserver observer;
  service->AddObserver(&observer);
  EXPECT_FALSE(observer.loaded_);

  std::string json_str(
      "{ \"recos\": [ "
      "{ \"contentInfo\": { \"url\" : \"http://localhost/foobar\" }}"
      "]}");
  EXPECT_TRUE(service->LoadFromJSONString(json_str));
  EXPECT_TRUE(observer.loaded_);

  service->RemoveObserver(&observer);
}

TEST_F(NTPSnippetsServiceTest, ObserverLoaded) {
  scoped_ptr<NTPSnippetsService> service(CreateSnippetService());

  std::string json_str(
      "{ \"recos\": [ "
      "{ \"contentInfo\": { \"url\" : \"http://localhost/foobar\" }}"
      "]}");
  EXPECT_TRUE(service->LoadFromJSONString(json_str));

  SnippetObserver observer;
  service->AddObserver(&observer);

  EXPECT_TRUE(observer.loaded_);

  service->RemoveObserver(&observer);
}
}  // namespace ntp_snippets
