// 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 <string>

#include "base/message_loop/message_loop.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/geolocation/geolocation_settings_state.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"

using content::BrowserThread;
using content::NavigationEntry;

namespace {

class GeolocationSettingsStateTests : public testing::Test {
 public:
  GeolocationSettingsStateTests()
    : ui_thread_(BrowserThread::UI, &message_loop_) {
  }

 protected:
  base::MessageLoop message_loop_;
  content::TestBrowserThread ui_thread_;
};

TEST_F(GeolocationSettingsStateTests, ClearOnNewOrigin) {
  TestingProfile profile;
  GeolocationSettingsState state(&profile);
  GURL url_0("http://www.example.com");

  scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
  entry->SetURL(url_0);
  content::LoadCommittedDetails load_committed_details;
  load_committed_details.entry = entry.get();
  state.DidNavigate(load_committed_details);

  HostContentSettingsMapFactory::GetForProfile(profile)->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      CONTENT_SETTINGS_TYPE_GEOLOCATION,
      std::string(),
      CONTENT_SETTING_ALLOW);
  state.OnGeolocationPermissionSet(url_0, true);

  GURL url_1("http://www.example1.com");
  HostContentSettingsMapFactory::GetForProfile(profile)->SetContentSetting(
    ContentSettingsPattern::FromURLNoWildcard(url_1),
    ContentSettingsPattern::FromURLNoWildcard(url_0),
    CONTENT_SETTINGS_TYPE_GEOLOCATION,
    std::string(),
    CONTENT_SETTING_BLOCK);
  state.OnGeolocationPermissionSet(url_1, false);

  GeolocationSettingsState::StateMap state_map =
      state.state_map();
  EXPECT_EQ(2U, state_map.size());

  GeolocationSettingsState::FormattedHostsPerState formatted_host_per_state;
  unsigned int tab_state_flags = 0;
  state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_ANY_ALLOWED)
              << tab_state_flags;
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_EXCEPTION)
              << tab_state_flags;
  EXPECT_FALSE(tab_state_flags &
               GeolocationSettingsState::TABSTATE_HAS_CHANGED)
               << tab_state_flags;
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_ANY_ICON)
              << tab_state_flags;
  EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_0.host()));

  EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
                url_1.host()));

  state.OnGeolocationPermissionSet(url_0, false);

  formatted_host_per_state.clear();
  tab_state_flags = 0;
  state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
  EXPECT_FALSE(tab_state_flags &
               GeolocationSettingsState::TABSTATE_HAS_ANY_ALLOWED)
               << tab_state_flags;
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_EXCEPTION)
              << tab_state_flags;
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_CHANGED)
              << tab_state_flags;
  EXPECT_TRUE(tab_state_flags &
              GeolocationSettingsState::TABSTATE_HAS_ANY_ICON)
              << tab_state_flags;
  EXPECT_EQ(0U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
  EXPECT_EQ(2U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
                url_0.host()));
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
                url_1.host()));

  state.OnGeolocationPermissionSet(url_0, true);

  load_committed_details.previous_url = url_0;
  state.DidNavigate(load_committed_details);

  GeolocationSettingsState::StateMap new_state_map =
      state.state_map();
  EXPECT_EQ(state_map.size(), new_state_map.size());

  GURL different_url("http://foo.com");
  entry->SetURL(different_url);
  state.DidNavigate(load_committed_details);

  EXPECT_TRUE(state.state_map().empty());

  formatted_host_per_state.clear();
  tab_state_flags = 0;
  state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
  EXPECT_TRUE(formatted_host_per_state.empty());
  EXPECT_EQ(0U, tab_state_flags);
}

TEST_F(GeolocationSettingsStateTests, ShowPortOnSameHost) {
  TestingProfile profile;
  GeolocationSettingsState state(&profile);
  GURL url_0("http://www.example.com");

  scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
  entry->SetURL(url_0);
  content::LoadCommittedDetails load_committed_details;
  load_committed_details.entry = entry.get();
  state.DidNavigate(load_committed_details);

  HostContentSettingsMapFactory::GetForProfile(profile)->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      CONTENT_SETTINGS_TYPE_GEOLOCATION,
      std::string(),
      CONTENT_SETTING_ALLOW);
  state.OnGeolocationPermissionSet(url_0, true);

  GURL url_1("https://www.example.com");
  HostContentSettingsMapFactory::GetForProfile(profile)->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(url_1),
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      CONTENT_SETTINGS_TYPE_GEOLOCATION,
      std::string(),
      CONTENT_SETTING_ALLOW);
  state.OnGeolocationPermissionSet(url_1, true);

  GURL url_2("http://www.example1.com");
  HostContentSettingsMapFactory::GetForProfile(profile)->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(url_2),
      ContentSettingsPattern::FromURLNoWildcard(url_0),
      CONTENT_SETTINGS_TYPE_GEOLOCATION,
      std::string(),
      CONTENT_SETTING_ALLOW);
  state.OnGeolocationPermissionSet(url_2, true);

  GeolocationSettingsState::StateMap state_map =
      state.state_map();
  EXPECT_EQ(3U, state_map.size());

  GeolocationSettingsState::FormattedHostsPerState formatted_host_per_state;
  unsigned int tab_state_flags = 0;
  state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);

  EXPECT_EQ(3U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_0.spec()));
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_1.spec()));
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_2.host()));

  state.OnGeolocationPermissionSet(url_1, false);
  formatted_host_per_state.clear();
  tab_state_flags = 0;
  state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);

  EXPECT_EQ(2U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_0.spec()));
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
                url_2.host()));
  EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
  EXPECT_EQ(1U,
            formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
                url_1.spec()));
}


}  // namespace
