// Copyright (c) 2012 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 "chrome/browser/sync/test/integration/search_engines_helper.h"

#include <vector>

#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"

using sync_datatype_helper::test;

namespace {

GUIDToTURLMap CreateGUIDToTURLMap(TemplateURLService* service) {
  CHECK(service);

  GUIDToTURLMap map;
  TemplateURLService::TemplateURLVector turls = service->GetTemplateURLs();
  for (TemplateURLService::TemplateURLVector::iterator it = turls.begin();
       it != turls.end(); ++it) {
    CHECK(*it);
    CHECK(map.find((*it)->sync_guid()) == map.end());
    map[(*it)->sync_guid()] = *it;
  }

  return map;
}

std::string GetTURLInfoString(const TemplateURL* turl) {
  DCHECK(turl);
  return "TemplateURL: shortname: " + UTF16ToASCII(turl->short_name()) +
      " keyword: " + UTF16ToASCII(turl->keyword()) + " url: " + turl->url();
}

bool TURLsMatch(const TemplateURL* turl1, const TemplateURL* turl2) {
  CHECK(turl1);
  CHECK(turl2);
  bool result = (turl1->url() == turl2->url()) &&
      (turl1->keyword() == turl2->keyword()) &&
      (turl1->short_name() == turl2->short_name());

  // Print some useful debug info.
  if (!result) {
    LOG(ERROR) << "TemplateURLs did not match: " << GetTURLInfoString(turl1)
               << " vs " << GetTURLInfoString(turl2);
  }

  return result;
}

bool ServicesMatch(int profile_a, int profile_b) {
  TemplateURLService* service_a =
      search_engines_helper::GetServiceForBrowserContext(profile_a);
  TemplateURLService* service_b =
      search_engines_helper::GetServiceForBrowserContext(profile_b);
  CHECK(service_a);
  CHECK(service_b);

  // Services that have synced should have identical TURLs, including the GUIDs.
  // Make sure we compare those fields in addition to the user-visible fields.
  GUIDToTURLMap a_turls = CreateGUIDToTURLMap(service_a);
  GUIDToTURLMap b_turls = CreateGUIDToTURLMap(service_b);

  if (a_turls.size() != b_turls.size()) {
    LOG(ERROR) << "Service a and b do not match in size: " << a_turls.size()
               << " vs " << b_turls.size() << " respectively.";
    return false;
  }

  for (GUIDToTURLMap::iterator it = a_turls.begin();
       it != a_turls.end(); ++it) {
    if (b_turls.find(it->first) == b_turls.end()) {
      LOG(ERROR) << "TURL GUID from a not found in b's TURLs: " << it->first;
      return false;
    }
    if (!TURLsMatch(b_turls[it->first], it->second))
      return false;
  }

  const TemplateURL* default_a = service_a->GetDefaultSearchProvider();
  const TemplateURL* default_b = service_b->GetDefaultSearchProvider();
  CHECK(default_a);
  CHECK(default_b);
  if (!TURLsMatch(default_a, default_b)) {
    LOG(ERROR) << "Default search providers do not match: A's default: "
               << default_a->keyword() << " B's default: "
               << default_b->keyword();
    return false;
  } else {
    LOG(INFO) << "A had default with URL: " << default_a->url()
              << " and keyword: " << default_a->keyword();
  }

  return true;
}

// Convenience helper for consistently generating the same keyword for a given
// seed.
base::string16 CreateKeyword(int seed) {
  return ASCIIToUTF16(base::StringPrintf("test%d", seed));
}

}  // namespace

namespace search_engines_helper {

TemplateURLService* GetServiceForBrowserContext(int profile_index) {
  return TemplateURLServiceFactory::GetForProfile(
      test()->GetProfile(profile_index));
}

TemplateURLService* GetVerifierService() {
  return TemplateURLServiceFactory::GetForProfile(test()->verifier());
}

bool ServiceMatchesVerifier(int profile_index) {
  TemplateURLService* verifier = GetVerifierService();
  TemplateURLService* other = GetServiceForBrowserContext(profile_index);

  CHECK(verifier);
  CHECK(other);

  TemplateURLService::TemplateURLVector verifier_turls =
      verifier->GetTemplateURLs();
  if (verifier_turls.size() != other->GetTemplateURLs().size()) {
    LOG(ERROR) << "Verifier and other service have a different count of TURLs: "
               << verifier_turls.size() << " vs "
               << other->GetTemplateURLs().size() << " respectively.";
    return false;
  }

  for (size_t i = 0; i < verifier_turls.size(); ++i) {
    const TemplateURL* verifier_turl = verifier_turls.at(i);
    CHECK(verifier_turl);
    const TemplateURL* other_turl = other->GetTemplateURLForKeyword(
        verifier_turl->keyword());

    if (!other_turl) {
      LOG(ERROR) << "The other service did not contain a TURL with keyword: "
                 << verifier_turl->keyword();
      return false;
    }
    if (!TURLsMatch(verifier_turl, other_turl))
      return false;
  }

  return true;
}

bool AllServicesMatch() {
  // Use 0 as the baseline.
  if (test()->use_verifier() && !ServiceMatchesVerifier(0)) {
    LOG(ERROR) << "TemplateURLService 0 does not match verifier.";
    return false;
  }

  for (int it = 1; it < test()->num_clients(); ++it) {
    if (!ServicesMatch(0, it)) {
      LOG(ERROR) << "TemplateURLService " << it << " does not match with "
                 << "service 0.";
      return false;
    }
  }
  return true;
}

TemplateURL* CreateTestTemplateURL(Profile* profile, int seed) {
  return CreateTestTemplateURL(profile, seed, CreateKeyword(seed),
                               base::StringPrintf("0000-0000-0000-%04d", seed));
}

TemplateURL* CreateTestTemplateURL(Profile* profile,
                                   int seed,
                                   const base::string16& keyword,
                                   const std::string& sync_guid) {
  return CreateTestTemplateURL(profile, seed, keyword,
      base::StringPrintf("http://www.test%d.com/", seed), sync_guid);
}

TemplateURL* CreateTestTemplateURL(Profile* profile,
                                   int seed,
                                   const base::string16& keyword,
                                   const std::string& url,
                                   const std::string& sync_guid) {
  TemplateURLData data;
  data.short_name = CreateKeyword(seed);
  data.SetKeyword(keyword);
  data.SetURL(url);
  data.favicon_url = GURL("http://favicon.url");
  data.safe_for_autoreplace = true;
  data.date_created = base::Time::FromTimeT(100);
  data.last_modified = base::Time::FromTimeT(100);
  data.prepopulate_id = 999999;
  data.sync_guid = sync_guid;
  return new TemplateURL(profile, data);
}

void AddSearchEngine(int profile_index, int seed) {
  Profile* profile = test()->GetProfile(profile_index);
  TemplateURLServiceFactory::GetForProfile(profile)->Add(
      CreateTestTemplateURL(profile, seed));
  if (test()->use_verifier())
    GetVerifierService()->Add(CreateTestTemplateURL(profile, seed));
}

void EditSearchEngine(int profile_index,
                      const base::string16& keyword,
                      const base::string16& short_name,
                      const base::string16& new_keyword,
                      const std::string& url) {
  DCHECK(!url.empty());
  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
  TemplateURL* turl = service->GetTemplateURLForKeyword(keyword);
  EXPECT_TRUE(turl);
  ASSERT_FALSE(new_keyword.empty());
  service->ResetTemplateURL(turl, short_name, new_keyword, url);
  // Make sure we do the same on the verifier.
  if (test()->use_verifier()) {
    TemplateURL* verifier_turl =
        GetVerifierService()->GetTemplateURLForKeyword(keyword);
    EXPECT_TRUE(verifier_turl);
    GetVerifierService()->ResetTemplateURL(verifier_turl, short_name,
                                           new_keyword, url);
  }
}

void DeleteSearchEngineBySeed(int profile_index, int seed) {
  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
  base::string16 keyword(CreateKeyword(seed));
  TemplateURL* turl = service->GetTemplateURLForKeyword(keyword);
  EXPECT_TRUE(turl);
  service->Remove(turl);
  // Make sure we do the same on the verifier.
  if (test()->use_verifier()) {
    TemplateURL* verifier_turl =
        GetVerifierService()->GetTemplateURLForKeyword(keyword);
    EXPECT_TRUE(verifier_turl);
    GetVerifierService()->Remove(verifier_turl);
  }
}

void ChangeDefaultSearchProvider(int profile_index, int seed) {
  TemplateURLService* service = GetServiceForBrowserContext(profile_index);
  ASSERT_TRUE(service);
  TemplateURL* turl = service->GetTemplateURLForKeyword(CreateKeyword(seed));
  ASSERT_TRUE(turl);
  service->SetDefaultSearchProvider(turl);
  if (test()->use_verifier()) {
    TemplateURL* verifier_turl =
        GetVerifierService()->GetTemplateURLForKeyword(CreateKeyword(seed));
    ASSERT_TRUE(verifier_turl);
    GetVerifierService()->SetDefaultSearchProvider(verifier_turl);
  }
}

}  // namespace search_engines_helper
