// Copyright (c) 2011 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/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/keyword_provider.h"
#include "chrome/browser/autocomplete/search_provider.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/test/testing_browser_process.h"
#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_profile.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_service.h"
#include "testing/gtest/include/gtest/gtest.h"

static std::ostream& operator<<(std::ostream& os,
                                const AutocompleteResult::const_iterator& it) {
  return os << static_cast<const AutocompleteMatch*>(&(*it));
}

namespace {

const size_t num_results_per_provider = 3;

// Autocomplete provider that provides known results. Note that this is
// refcounted so that it can also be a task on the message loop.
class TestProvider : public AutocompleteProvider {
 public:
  TestProvider(int relevance, const string16& prefix)
      : AutocompleteProvider(NULL, NULL, ""),
        relevance_(relevance),
        prefix_(prefix) {
  }

  virtual void Start(const AutocompleteInput& input,
                     bool minimal_changes);

  void set_listener(ACProviderListener* listener) {
    listener_ = listener;
  }

 private:
  ~TestProvider() {}

  void Run();

  void AddResults(int start_at, int num);

  int relevance_;
  const string16 prefix_;
};

void TestProvider::Start(const AutocompleteInput& input,
                         bool minimal_changes) {
  if (minimal_changes)
    return;

  matches_.clear();

  // Generate one result synchronously, the rest later.
  AddResults(0, 1);

  if (input.matches_requested() == AutocompleteInput::ALL_MATCHES) {
    done_ = false;
    MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
        this, &TestProvider::Run));
  }
}

void TestProvider::Run() {
  DCHECK_GT(num_results_per_provider, 0U);
  AddResults(1, num_results_per_provider);
  done_ = true;
  DCHECK(listener_);
  listener_->OnProviderUpdate(true);
}

void TestProvider::AddResults(int start_at, int num) {
  for (int i = start_at; i < num; i++) {
    AutocompleteMatch match(this, relevance_ - i, false,
                            AutocompleteMatch::URL_WHAT_YOU_TYPED);

    match.fill_into_edit = prefix_ + UTF8ToUTF16(base::IntToString(i));
    match.destination_url = GURL(UTF16ToUTF8(match.fill_into_edit));

    match.contents = match.fill_into_edit;
    match.contents_class.push_back(
        ACMatchClassification(0, ACMatchClassification::NONE));
    match.description = match.fill_into_edit;
    match.description_class.push_back(
        ACMatchClassification(0, ACMatchClassification::NONE));

    matches_.push_back(match);
  }
}

class AutocompleteProviderTest : public testing::Test,
                                 public NotificationObserver {
 protected:
  void ResetControllerWithTestProviders(bool same_destinations);

  // Runs a query on the input "a", and makes sure both providers' input is
  // properly collected.
  void RunTest();

  void ResetControllerWithTestProvidersWithKeywordAndSearchProviders();
  void RunExactKeymatchTest(bool allow_exact_keyword_match);

  // These providers are owned by the controller once it's created.
  ACProviders providers_;

  AutocompleteResult result_;

 private:
  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  ScopedTestingBrowserProcess browser_process_;

  MessageLoopForUI message_loop_;
  scoped_ptr<AutocompleteController> controller_;
  NotificationRegistrar registrar_;
  TestingProfile profile_;
};

void AutocompleteProviderTest::ResetControllerWithTestProviders(
    bool same_destinations) {
  // Forget about any existing providers.  The controller owns them and will
  // Release() them below, when we delete it during the call to reset().
  providers_.clear();

  // Construct two new providers, with either the same or different prefixes.
  TestProvider* providerA = new TestProvider(num_results_per_provider,
                                             ASCIIToUTF16("http://a"));
  providerA->AddRef();
  providers_.push_back(providerA);

  TestProvider* providerB = new TestProvider(num_results_per_provider * 2,
      same_destinations ? ASCIIToUTF16("http://a") : ASCIIToUTF16("http://b"));
  providerB->AddRef();
  providers_.push_back(providerB);

  // Reset the controller to contain our new providers.
  AutocompleteController* controller = new AutocompleteController(providers_);
  controller_.reset(controller);
  providerA->set_listener(controller);
  providerB->set_listener(controller);

  // The providers don't complete synchronously, so listen for "result updated"
  // notifications.
  registrar_.Add(this, NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_READY,
                 NotificationService::AllSources());
}

void AutocompleteProviderTest::
    ResetControllerWithTestProvidersWithKeywordAndSearchProviders() {
  profile_.CreateTemplateURLModel();

  // Reset the default TemplateURL.
  TemplateURL* default_t_url = new TemplateURL();
  default_t_url->SetURL("http://defaultturl/{searchTerms}", 0, 0);
  TemplateURLModel* turl_model = profile_.GetTemplateURLModel();
  turl_model->Add(default_t_url);
  turl_model->SetDefaultSearchProvider(default_t_url);
  TemplateURLID default_provider_id = default_t_url->id();
  ASSERT_NE(0, default_provider_id);

  // Create another TemplateURL for KeywordProvider.
  TemplateURL* keyword_t_url = new TemplateURL();
  keyword_t_url->set_short_name(ASCIIToUTF16("k"));
  keyword_t_url->set_keyword(ASCIIToUTF16("k"));
  keyword_t_url->SetURL("http://keyword/{searchTerms}", 0, 0);
  profile_.GetTemplateURLModel()->Add(keyword_t_url);
  ASSERT_NE(0, keyword_t_url->id());

  // Forget about any existing providers.  The controller owns them and will
  // Release() them below, when we delete it during the call to reset().
  providers_.clear();

  // Create both a keyword and search provider, and add them in that order.
  // (Order is important; see comments in RunExactKeymatchTest().)
  AutocompleteProvider* keyword_provider = new KeywordProvider(NULL,
                                                                &profile_);
  keyword_provider->AddRef();
  providers_.push_back(keyword_provider);
  AutocompleteProvider* search_provider = new SearchProvider(NULL, &profile_);
  search_provider->AddRef();
  providers_.push_back(search_provider);

  AutocompleteController* controller = new AutocompleteController(providers_);
  controller_.reset(controller);
}

void AutocompleteProviderTest::RunTest() {
  result_.Reset();
  controller_->Start(ASCIIToUTF16("a"), string16(), true, false, true,
                     AutocompleteInput::ALL_MATCHES);

  // The message loop will terminate when all autocomplete input has been
  // collected.
  MessageLoop::current()->Run();
}

void AutocompleteProviderTest::RunExactKeymatchTest(
    bool allow_exact_keyword_match) {
  // Send the controller input which exactly matches the keyword provider we
  // created in ResetControllerWithKeywordAndSearchProviders().  The default
  // match should thus be a keyword match iff |allow_exact_keyword_match| is
  // true.
  controller_->Start(ASCIIToUTF16("k test"), string16(), true, false,
                     allow_exact_keyword_match,
                     AutocompleteInput::SYNCHRONOUS_MATCHES);
  EXPECT_TRUE(controller_->done());
  // ResetControllerWithKeywordAndSearchProviders() adds the keyword provider
  // first, then the search provider.  So if the default match is a keyword
  // match, it will come from provider 0, otherwise from provider 1.
  EXPECT_EQ(providers_[allow_exact_keyword_match ? 0 : 1],
      controller_->result().default_match()->provider);
}

void AutocompleteProviderTest::Observe(NotificationType type,
                                       const NotificationSource& source,
                                       const NotificationDetails& details) {
  if (controller_->done()) {
    result_.CopyFrom(controller_->result());
    MessageLoop::current()->Quit();
  }
}

// Tests that the default selection is set properly when updating results.
TEST_F(AutocompleteProviderTest, Query) {
  ResetControllerWithTestProviders(false);
  RunTest();

  // Make sure the default match gets set to the highest relevance match.  The
  // highest relevance matches should come from the second provider.
  EXPECT_EQ(num_results_per_provider * 2, result_.size());  // two providers
  ASSERT_NE(result_.end(), result_.default_match());
  EXPECT_EQ(providers_[1], result_.default_match()->provider);
}

TEST_F(AutocompleteProviderTest, RemoveDuplicates) {
  ResetControllerWithTestProviders(true);
  RunTest();

  // Make sure all the first provider's results were eliminated by the second
  // provider's.
  EXPECT_EQ(num_results_per_provider, result_.size());
  for (AutocompleteResult::const_iterator i(result_.begin());
       i != result_.end(); ++i)
    EXPECT_EQ(providers_[1], i->provider);
}

TEST_F(AutocompleteProviderTest, AllowExactKeywordMatch) {
  ResetControllerWithTestProvidersWithKeywordAndSearchProviders();
  RunExactKeymatchTest(true);
  RunExactKeymatchTest(false);
}

typedef TestingBrowserProcessTest AutocompleteTest;

TEST_F(AutocompleteTest, InputType) {
  struct test_data {
    const string16 input;
    const AutocompleteInput::Type type;
  } input_cases[] = {
    { ASCIIToUTF16(""), AutocompleteInput::INVALID },
    { ASCIIToUTF16("?"), AutocompleteInput::FORCED_QUERY },
    { ASCIIToUTF16("?foo"), AutocompleteInput::FORCED_QUERY },
    { ASCIIToUTF16("?foo bar"), AutocompleteInput::FORCED_QUERY },
    { ASCIIToUTF16("?http://foo.com/bar"), AutocompleteInput::FORCED_QUERY },
    { ASCIIToUTF16("foo"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("foo.c"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("-.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("foo/bar"), AutocompleteInput::URL },
    { ASCIIToUTF16("foo;bar"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("foo/bar baz"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("foo bar.com"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("foo bar"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("foo+bar"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("foo+bar.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("\"foo:bar\""), AutocompleteInput::QUERY },
    { ASCIIToUTF16("link:foo.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("foo:81"), AutocompleteInput::URL },
    { ASCIIToUTF16("www.foo.com:81"), AutocompleteInput::URL },
    { ASCIIToUTF16("localhost:8080"), AutocompleteInput::URL },
    { ASCIIToUTF16("foo.com:123456"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("foo.com:abc"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("1.2.3.4:abc"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("user@foo.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("user:pass@"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("user:pass@!foo.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("user:pass@foo"), AutocompleteInput::URL },
    { ASCIIToUTF16("user:pass@foo.c"), AutocompleteInput::URL },
    { ASCIIToUTF16("user:pass@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("user:pass@foo.com:81"), AutocompleteInput::URL },
    { ASCIIToUTF16("user:pass@foo:81"), AutocompleteInput::URL },
    { ASCIIToUTF16("1.2"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("1.2/45"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("1.2:45"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("user@1.2:45"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("user:pass@1.2:45"), AutocompleteInput::URL },
    { ASCIIToUTF16("ps/2 games"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("en.wikipedia.org/wiki/James Bond"),
        AutocompleteInput::URL },
    // In Chrome itself, mailto: will get handled by ShellExecute, but in
    // unittest mode, we don't have the data loaded in the external protocol
    // handler to know this.
    // { ASCIIToUTF16("mailto:abuse@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("view-source:http://www.foo.com/"), AutocompleteInput::URL },
    { ASCIIToUTF16("javascript:alert(\"Hey there!\");"),
        AutocompleteInput::URL },
#if defined(OS_WIN)
    { ASCIIToUTF16("C:\\Program Files"), AutocompleteInput::URL },
    { ASCIIToUTF16("\\\\Server\\Folder\\File"), AutocompleteInput::URL },
#endif  // defined(OS_WIN)
    { ASCIIToUTF16("http:foo"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://foo"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://foo.c"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://foo_bar.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://foo/bar baz"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://-.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("http://_foo_.com"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("http://foo.com:abc"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("http://foo.com:123456"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("http://1.2.3.4:abc"), AutocompleteInput::QUERY },
    { ASCIIToUTF16("http:user@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://user@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http:user:pass@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://user:pass@foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://1.2"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://1.2/45"), AutocompleteInput::URL },
    { ASCIIToUTF16("http:ps/2 games"), AutocompleteInput::URL },
    { ASCIIToUTF16("http://ps/2 games"), AutocompleteInput::URL },
    { ASCIIToUTF16("https://foo.com"), AutocompleteInput::URL },
    { ASCIIToUTF16("127.0.0.1"), AutocompleteInput::URL },
    { ASCIIToUTF16("127.0.1"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("127.0.1/"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("browser.tabs.closeButtons"), AutocompleteInput::UNKNOWN },
    { WideToUTF16(L"\u6d4b\u8bd5"), AutocompleteInput::UNKNOWN },
    { ASCIIToUTF16("[2001:]"), AutocompleteInput::QUERY },  // Not a valid IP
    { ASCIIToUTF16("[2001:dB8::1]"), AutocompleteInput::URL },
    { ASCIIToUTF16("192.168.0.256"),
        AutocompleteInput::QUERY },  // Invalid IPv4 literal.
    { ASCIIToUTF16("[foo.com]"),
        AutocompleteInput::QUERY },  // Invalid IPv6 literal.
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
    SCOPED_TRACE(input_cases[i].input);
    AutocompleteInput input(input_cases[i].input, string16(), true, false,
                            true, AutocompleteInput::ALL_MATCHES);
    EXPECT_EQ(input_cases[i].type, input.type());
  }
}

TEST_F(AutocompleteTest, InputTypeWithDesiredTLD) {
  struct test_data {
    const string16 input;
    const AutocompleteInput::Type type;
  } input_cases[] = {
    { ASCIIToUTF16("401k"), AutocompleteInput::REQUESTED_URL },
    { ASCIIToUTF16("999999999999999"), AutocompleteInput::REQUESTED_URL },
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
    AutocompleteInput input(input_cases[i].input, ASCIIToUTF16("com"), true,
                            false, true, AutocompleteInput::ALL_MATCHES);
    EXPECT_EQ(input_cases[i].type, input.type()) << "Input: " <<
        input_cases[i].input;
  }
}

// This tests for a regression where certain input in the omnibox caused us to
// crash. As long as the test completes without crashing, we're fine.
TEST_F(AutocompleteTest, InputCrash) {
  AutocompleteInput input(WideToUTF16(L"\uff65@s"), string16(), true, false,
                          true, AutocompleteInput::ALL_MATCHES);
}

// Test comparing matches relevance.
TEST(AutocompleteMatch, MoreRelevant) {
  struct RelevantCases {
    int r1;
    int r2;
    bool expected_result;
  } cases[] = {
    {  10,   0, true  },
    {  10,  -5, true  },
    {  -5,  10, false },
    {   0,  10, false },
    { -10,  -5, false  },
    {  -5, -10, true },
  };

  AutocompleteMatch m1(NULL, 0, false, AutocompleteMatch::URL_WHAT_YOU_TYPED);
  AutocompleteMatch m2(NULL, 0, false, AutocompleteMatch::URL_WHAT_YOU_TYPED);

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    m1.relevance = cases[i].r1;
    m2.relevance = cases[i].r2;
    EXPECT_EQ(cases[i].expected_result,
              AutocompleteMatch::MoreRelevant(m1, m2));
  }
}

TEST(AutocompleteInput, ParseForEmphasizeComponent) {
  using url_parse::Component;
  Component kInvalidComponent(0, -1);
  struct test_data {
    const string16 input;
    const Component scheme;
    const Component host;
  } input_cases[] = {
    { ASCIIToUTF16(""), kInvalidComponent, kInvalidComponent },
    { ASCIIToUTF16("?"), kInvalidComponent, kInvalidComponent },
    { ASCIIToUTF16("?http://foo.com/bar"), kInvalidComponent,
        kInvalidComponent },
    { ASCIIToUTF16("foo/bar baz"), kInvalidComponent, Component(0, 3) },
    { ASCIIToUTF16("http://foo/bar baz"), Component(0, 4), Component(7, 3) },
    { ASCIIToUTF16("link:foo.com"), Component(0, 4), kInvalidComponent },
    { ASCIIToUTF16("www.foo.com:81"), kInvalidComponent, Component(0, 11) },
    { WideToUTF16(L"\u6d4b\u8bd5"), kInvalidComponent, Component(0, 2) },
    { ASCIIToUTF16("view-source:http://www.foo.com/"), Component(12, 4),
        Component(19, 11) },
    { ASCIIToUTF16("view-source:https://example.com/"),
      Component(12, 5), Component(20, 11) },
    { ASCIIToUTF16("view-source:www.foo.com"), kInvalidComponent,
        Component(12, 11) },
    { ASCIIToUTF16("view-source:"), Component(0, 11), kInvalidComponent },
    { ASCIIToUTF16("view-source:garbage"), kInvalidComponent,
        Component(12, 7) },
    { ASCIIToUTF16("view-source:http://http://foo"), Component(12, 4),
        Component(19, 4) },
    { ASCIIToUTF16("view-source:view-source:http://example.com/"),
        Component(12, 11), kInvalidComponent }
  };

  ScopedTestingBrowserProcess browser_process;

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
    Component scheme, host;
    AutocompleteInput::ParseForEmphasizeComponents(input_cases[i].input,
                                                   string16(),
                                                   &scheme,
                                                   &host);
    AutocompleteInput input(input_cases[i].input, string16(), true, false,
                            true, AutocompleteInput::ALL_MATCHES);
    EXPECT_EQ(input_cases[i].scheme.begin, scheme.begin) << "Input: " <<
        input_cases[i].input;
    EXPECT_EQ(input_cases[i].scheme.len, scheme.len) << "Input: " <<
        input_cases[i].input;
    EXPECT_EQ(input_cases[i].host.begin, host.begin) << "Input: " <<
        input_cases[i].input;
    EXPECT_EQ(input_cases[i].host.len, host.len) << "Input: " <<
        input_cases[i].input;
  }
}

}  // namespace
