// Copyright (c) 2013 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/dns/record_rdata.h"

#include "base/memory/scoped_ptr.h"
#include "net/base/ip_address_number.h"
#include "net/dns/dns_response.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

base::StringPiece MakeStringPiece(const uint8* data, unsigned size) {
  const char* data_cc = reinterpret_cast<const char*>(data);
  return base::StringPiece(data_cc, size);
}

TEST(RecordRdataTest, ParseSrvRecord) {
  scoped_ptr<SrvRecordRdata> record1_obj;
  scoped_ptr<SrvRecordRdata> record2_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x00, 0x01,
    0x00, 0x02,
    0x00, 0x50,
    0x03, 'w', 'w', 'w',
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
    0x03, 'c', 'o', 'm',
    0x00,
    0x01, 0x01,
    0x01, 0x02,
    0x01, 0x03,
    0x04, 'w', 'w', 'w', '2',
    0xc0, 0x0a,  // Pointer to "google.com"
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  const unsigned first_record_len = 22;
  base::StringPiece record1_strpiece = MakeStringPiece(
      record, first_record_len);
  base::StringPiece record2_strpiece = MakeStringPiece(
      record + first_record_len, sizeof(record) - first_record_len);

  record1_obj = SrvRecordRdata::Create(record1_strpiece, parser);
  ASSERT_TRUE(record1_obj != NULL);
  ASSERT_EQ(1, record1_obj->priority());
  ASSERT_EQ(2, record1_obj->weight());
  ASSERT_EQ(80, record1_obj->port());

  ASSERT_EQ("www.google.com", record1_obj->target());

  record2_obj = SrvRecordRdata::Create(record2_strpiece, parser);
  ASSERT_TRUE(record2_obj != NULL);
  ASSERT_EQ(257, record2_obj->priority());
  ASSERT_EQ(258, record2_obj->weight());
  ASSERT_EQ(259, record2_obj->port());

  ASSERT_EQ("www2.google.com", record2_obj->target());

  ASSERT_TRUE(record1_obj->IsEqual(record1_obj.get()));
  ASSERT_FALSE(record1_obj->IsEqual(record2_obj.get()));
}

TEST(RecordRdataTest, ParseARecord) {
  scoped_ptr<ARecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x7F, 0x00, 0x00, 0x01  // 127.0.0.1
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = ARecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  ASSERT_EQ("127.0.0.1", IPAddressToString(record_obj->address()));

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}

TEST(RecordRdataTest, ParseAAAARecord) {
  scoped_ptr<AAAARecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x12, 0x34, 0x56, 0x78,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x09  // 1234:5678::9A
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = AAAARecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  ASSERT_EQ("1234:5678::9",
            IPAddressToString(record_obj->address()));

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}

TEST(RecordRdataTest, ParseCnameRecord) {
  scoped_ptr<CnameRecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x03, 'w', 'w', 'w',
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
    0x03, 'c', 'o', 'm',
    0x00
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = CnameRecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  ASSERT_EQ("www.google.com", record_obj->cname());

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}

TEST(RecordRdataTest, ParsePtrRecord) {
  scoped_ptr<PtrRecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x03, 'w', 'w', 'w',
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
    0x03, 'c', 'o', 'm',
    0x00
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = PtrRecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  ASSERT_EQ("www.google.com", record_obj->ptrdomain());

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}

TEST(RecordRdataTest, ParseTxtRecord) {
  scoped_ptr<TxtRecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x03, 'w', 'w', 'w',
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
    0x03, 'c', 'o', 'm'
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = TxtRecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  std::vector<std::string> expected;
  expected.push_back("www");
  expected.push_back("google");
  expected.push_back("com");

  ASSERT_EQ(expected, record_obj->texts());

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}

TEST(RecordRdataTest, ParseNsecRecord) {
  scoped_ptr<NsecRecordRdata> record_obj;

  // These are just the rdata portions of the DNS records, rather than complete
  // records, but it works well enough for this test.

  const uint8 record[] = {
    0x03, 'w', 'w', 'w',
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
    0x03, 'c', 'o', 'm',
    0x00,
    0x00, 0x02, 0x40, 0x01
  };

  DnsRecordParser parser(record, sizeof(record), 0);
  base::StringPiece record_strpiece = MakeStringPiece(record, sizeof(record));

  record_obj = NsecRecordRdata::Create(record_strpiece, parser);
  ASSERT_TRUE(record_obj != NULL);

  ASSERT_EQ(16u, record_obj->bitmap_length());

  EXPECT_FALSE(record_obj->GetBit(0));
  EXPECT_TRUE(record_obj->GetBit(1));
  for (int i = 2; i < 15; i++) {
    EXPECT_FALSE(record_obj->GetBit(i));
  }
  EXPECT_TRUE(record_obj->GetBit(15));

  ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
}


}  // namespace net
