// 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 "net/base/host_port_pair.h"

#include "base/logging.h"
#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"

using std::string;

namespace net {

namespace {

struct TestData {
  string host;
  uint16 port;
  string to_string;
  string host_for_url;
} tests[] = {
  { "www.google.com", 80, "www.google.com:80", "www.google.com" },
  { "www.google.com", 443, "www.google.com:443", "www.google.com" },
  { "127.0.0.1", 80, "127.0.0.1:80", "127.0.0.1" },
  { "192.168.1.1", 80, "192.168.1.1:80", "192.168.1.1" },
  { "::1", 80, "[::1]:80", "[::1]" },
  { "2001:db8::42", 80, "[2001:db8::42]:80", "[2001:db8::42]" },
};

TEST(HostPortPairTest, Parsing) {
  HostPortPair foo("foo.com", 10);
  string foo_str = foo.ToString();
  EXPECT_EQ("foo.com:10", foo_str);
  HostPortPair bar = HostPortPair::FromString(foo_str);
  EXPECT_TRUE(foo.Equals(bar));
}

TEST(HostPortPairTest, BadString) {
  HostPortPair foo = HostPortPair::FromString("foo.com:2:3");
  EXPECT_TRUE(foo.host().empty());
  EXPECT_EQ(0, foo.port());

  HostPortPair bar = HostPortPair::FromString("bar.com:two");
  EXPECT_TRUE(bar.host().empty());
  EXPECT_EQ(0, bar.port());
}

TEST(HostPortPairTest, Emptiness) {
  HostPortPair foo;
  EXPECT_TRUE(foo.IsEmpty());
  foo = HostPortPair::FromString("foo.com:8080");
  EXPECT_FALSE(foo.IsEmpty());
}

TEST(HostPortPairTest, ToString) {
  for (size_t index = 0; index < arraysize(tests); ++index) {
    HostPortPair foo(tests[index].host, tests[index].port);
    EXPECT_EQ(tests[index].to_string, foo.ToString());
  }

  // Test empty hostname.
  HostPortPair foo(string(), 10);
}

TEST(HostPortPairTest, HostForURL) {
  for (size_t index = 0; index < arraysize(tests); ++index) {
    HostPortPair foo(tests[index].host, tests[index].port);
    EXPECT_EQ(tests[index].host_for_url, foo.HostForURL());
  }

  // Test hostname with null character.
  string bar_hostname("a\0.\0com", 7);
  HostPortPair bar(bar_hostname, 80);
  string expected_error("Host has a null char: a%00.%00com");
  EXPECT_DFATAL(bar.HostForURL(), expected_error);
}

TEST(HostPortPairTest, LessThan) {
  HostPortPair a_10("a.com", 10);
  HostPortPair a_11("a.com", 11);
  HostPortPair b_10("b.com", 10);
  HostPortPair b_11("b.com", 11);

  EXPECT_FALSE(a_10 < a_10);
  EXPECT_TRUE(a_10  < a_11);
  EXPECT_TRUE(a_10  < b_10);
  EXPECT_TRUE(a_10  < b_11);

  EXPECT_FALSE(a_11 < a_10);
  EXPECT_FALSE(a_11 < b_10);

  EXPECT_FALSE(b_10 < a_10);
  EXPECT_TRUE(b_10  < a_11);

  EXPECT_FALSE(b_11 < a_10);
}

TEST(HostPortPairTest, Equals) {
  HostPortPair a_10("a.com", 10);
  HostPortPair a_11("a.com", 11);
  HostPortPair b_10("b.com", 10);
  HostPortPair b_11("b.com", 11);

  HostPortPair new_a_10("a.com", 10);

  EXPECT_TRUE(new_a_10.Equals(a_10));
  EXPECT_FALSE(new_a_10.Equals(a_11));
  EXPECT_FALSE(new_a_10.Equals(b_10));
  EXPECT_FALSE(new_a_10.Equals(b_11));
}

}  // namespace

}  // namespace net
