// 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_parsed.h"

#include "base/logging.h"
#include "net/dns/dns_response.h"
#include "net/dns/record_rdata.h"

namespace net {

RecordParsed::RecordParsed(const std::string& name, uint16 type, uint16 klass,
                           uint32 ttl, scoped_ptr<const RecordRdata> rdata,
                           base::Time time_created)
    : name_(name), type_(type), klass_(klass), ttl_(ttl), rdata_(rdata.Pass()),
      time_created_(time_created) {
}

RecordParsed::~RecordParsed() {
}

// static
scoped_ptr<const RecordParsed> RecordParsed::CreateFrom(
    DnsRecordParser* parser,
    base::Time time_created) {
  DnsResourceRecord record;
  scoped_ptr<const RecordRdata> rdata;

  if (!parser->ReadRecord(&record))
    return scoped_ptr<const RecordParsed>();

  switch (record.type) {
    case ARecordRdata::kType:
      rdata = ARecordRdata::Create(record.rdata, *parser);
      break;
    case AAAARecordRdata::kType:
      rdata = AAAARecordRdata::Create(record.rdata, *parser);
      break;
    case CnameRecordRdata::kType:
      rdata = CnameRecordRdata::Create(record.rdata, *parser);
      break;
    case PtrRecordRdata::kType:
      rdata = PtrRecordRdata::Create(record.rdata, *parser);
      break;
    case SrvRecordRdata::kType:
      rdata = SrvRecordRdata::Create(record.rdata, *parser);
      break;
    case TxtRecordRdata::kType:
      rdata = TxtRecordRdata::Create(record.rdata, *parser);
      break;
    case NsecRecordRdata::kType:
      rdata = NsecRecordRdata::Create(record.rdata, *parser);
      break;
    default:
      DVLOG(1) << "Unknown RData type for received record: " << record.type;
      return scoped_ptr<const RecordParsed>();
  }

  if (!rdata.get())
    return scoped_ptr<const RecordParsed>();

  return scoped_ptr<const RecordParsed>(new RecordParsed(record.name,
                                                         record.type,
                                                         record.klass,
                                                         record.ttl,
                                                         rdata.Pass(),
                                                         time_created));
}

bool RecordParsed::IsEqual(const RecordParsed* other, bool is_mdns) const {
  DCHECK(other);
  uint16 klass = klass_;
  uint16 other_klass = other->klass_;

  if (is_mdns) {
    klass &= dns_protocol::kMDnsClassMask;
    other_klass &= dns_protocol::kMDnsClassMask;
  }

  return name_ == other->name_ &&
      klass == other_klass &&
      type_ == other->type_ &&
      rdata_->IsEqual(other->rdata_.get());
}
}
