// Copyright (c) 2016 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/unguessable_token.h"

#include <memory>
#include <sstream>
#include <type_traits>

#include "base/value_conversions.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

void TestSmallerThanOperator(const UnguessableToken& a,
                             const UnguessableToken& b) {
  EXPECT_TRUE(a < b);
  EXPECT_FALSE(b < a);
}

TEST(UnguessableTokenTest, VerifyEqualityOperators) {
  // Deserialize is used for testing purposes.
  // Use UnguessableToken::Create() in production code instead.
  UnguessableToken token = UnguessableToken::Deserialize(1, 2);
  UnguessableToken same_token = UnguessableToken::Deserialize(1, 2);
  UnguessableToken diff_token = UnguessableToken::Deserialize(1, 3);

  EXPECT_TRUE(token == token);
  EXPECT_FALSE(token != token);

  EXPECT_TRUE(token == same_token);
  EXPECT_FALSE(token != same_token);

  EXPECT_FALSE(token == diff_token);
  EXPECT_FALSE(diff_token == token);
  EXPECT_TRUE(token != diff_token);
  EXPECT_TRUE(diff_token != token);
}

TEST(UnguessableTokenTest, VerifyConstructors) {
  UnguessableToken token = UnguessableToken::Create();
  EXPECT_FALSE(token.is_empty());
  EXPECT_TRUE(token);

  UnguessableToken copied_token(token);
  EXPECT_TRUE(copied_token);
  EXPECT_EQ(token, copied_token);

  UnguessableToken uninitialized;
  EXPECT_TRUE(uninitialized.is_empty());
  EXPECT_FALSE(uninitialized);

  EXPECT_TRUE(UnguessableToken().is_empty());
  EXPECT_FALSE(UnguessableToken());
}

TEST(UnguessableTokenTest, VerifySerialization) {
  UnguessableToken token = UnguessableToken::Create();

  uint64_t high = token.GetHighForSerialization();
  uint64_t low = token.GetLowForSerialization();

  EXPECT_TRUE(high);
  EXPECT_TRUE(low);

  UnguessableToken Deserialized = UnguessableToken::Deserialize(high, low);
  EXPECT_EQ(token, Deserialized);
}

TEST(UnguessableTokenTest, VerifyValueSerialization) {
  UnguessableToken token = UnguessableToken::Create();
  Value value = CreateUnguessableTokenValue(token);

  UnguessableToken deserialized;
  EXPECT_TRUE(GetValueAsUnguessableToken(value, &deserialized));
  EXPECT_EQ(token, deserialized);
}

// Common case (~88% of the time) - no leading zeroes in high_ nor low_.
TEST(UnguessableTokenTest, VerifyToString1) {
  UnguessableToken token =
      UnguessableToken::Deserialize(0x1234567890ABCDEF, 0xFEDCBA0987654321);
  std::string expected = "1234567890ABCDEFFEDCBA0987654321";

  EXPECT_EQ(expected, token.ToString());

  std::string expected_stream = "(1234567890ABCDEFFEDCBA0987654321)";
  std::stringstream stream;
  stream << token;
  EXPECT_EQ(expected_stream, stream.str());
}

// Less common case - leading zeroes in high_ or low_ (testing with both).
TEST(UnguessableTokenTest, VerifyToString2) {
  UnguessableToken token = UnguessableToken::Deserialize(0x123, 0xABC);
  std::string expected = "00000000000001230000000000000ABC";

  EXPECT_EQ(expected, token.ToString());

  std::string expected_stream = "(00000000000001230000000000000ABC)";
  std::stringstream stream;
  stream << token;
  EXPECT_EQ(expected_stream, stream.str());
}

TEST(UnguessableTokenTest, VerifyToStringUniqueness) {
  const UnguessableToken token1 =
      UnguessableToken::Deserialize(0x0000000012345678, 0x0000000123456789);
  const UnguessableToken token2 =
      UnguessableToken::Deserialize(0x0000000123456781, 0x0000000023456789);
  EXPECT_NE(token1.ToString(), token2.ToString());
}

TEST(UnguessableTokenTest, VerifySmallerThanOperator) {
  // Deserialize is used for testing purposes.
  // Use UnguessableToken::Create() in production code instead.
  {
    SCOPED_TRACE("a.low < b.low and a.high == b.high.");
    TestSmallerThanOperator(UnguessableToken::Deserialize(0, 1),
                            UnguessableToken::Deserialize(0, 5));
  }
  {
    SCOPED_TRACE("a.low == b.low and a.high < b.high.");
    TestSmallerThanOperator(UnguessableToken::Deserialize(1, 0),
                            UnguessableToken::Deserialize(5, 0));
  }
  {
    SCOPED_TRACE("a.low < b.low and a.high < b.high.");
    TestSmallerThanOperator(UnguessableToken::Deserialize(1, 1),
                            UnguessableToken::Deserialize(5, 5));
  }
  {
    SCOPED_TRACE("a.low > b.low and a.high < b.high.");
    TestSmallerThanOperator(UnguessableToken::Deserialize(1, 10),
                            UnguessableToken::Deserialize(10, 1));
  }
}

TEST(UnguessableTokenTest, VerifyHash) {
  UnguessableToken token = UnguessableToken::Create();

  EXPECT_EQ(base::HashInts64(token.GetHighForSerialization(),
                             token.GetLowForSerialization()),
            UnguessableTokenHash()(token));
}

TEST(UnguessableTokenTest, VerifyBasicUniqueness) {
  EXPECT_NE(UnguessableToken::Create(), UnguessableToken::Create());

  UnguessableToken token = UnguessableToken::Create();
  EXPECT_NE(token.GetHighForSerialization(), token.GetLowForSerialization());
}
}
