// Copyright 2017 The Fuchsia 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 "src/connectivity/network/mdns/service/encoding/dns_message.h"

namespace mdns {

void DnsHeader::SetResponse(bool value) {
  if (value) {
    flags_ |= kQueryResponseMask;
  } else {
    flags_ &= ~kQueryResponseMask;
  }
}

void DnsHeader::SetOpCode(DnsOpCode op_code) {
  flags_ &= ~kOpCodeMask;
  flags_ |= static_cast<uint16_t>(op_code) << kOpCodeShift;
}

void DnsHeader::SetAuthoritativeAnswer(bool value) {
  if (value) {
    flags_ |= kAuthoritativeAnswerMask;
  } else {
    flags_ &= ~kAuthoritativeAnswerMask;
  }
}

void DnsHeader::SetTruncated(bool value) {
  if (value) {
    flags_ |= kTruncationMask;
  } else {
    flags_ &= ~kTruncationMask;
  }
}

void DnsHeader::SetRecursionDesired(bool value) {
  if (value) {
    flags_ |= kRecursionDesiredMask;
  } else {
    flags_ &= ~kRecursionDesiredMask;
  }
}

void DnsHeader::SetRecursionAvailable(bool value) {
  if (value) {
    flags_ |= kRecursionAvailableMask;
  } else {
    flags_ &= ~kRecursionAvailableMask;
  }
}

void DnsHeader::SetResponseCode(DnsResponseCode response_code) {
  flags_ &= ~kResponseCodeMask;
  flags_ |= static_cast<uint16_t>(response_code);
}

DnsQuestion::DnsQuestion() {}

DnsQuestion::DnsQuestion(const std::string& name, DnsType type)
    : name_(DnsName(name)), type_(type) {}

DnsQuestion::DnsQuestion(const std::string& name, DnsType type, bool request_unicast_response)
    : name_(DnsName(name)), type_(type), unicast_response_(request_unicast_response) {}

DnsResource::DnsResource() {}

DnsResource::DnsResource(const std::string& name, DnsType type)
    : name_(DnsName(name)), type_(type) {
  switch (type_) {
    case DnsType::kA:
      new (&a_) DnsResourceDataA();
      time_to_live_ = kShortTimeToLive;
      // cache_flush_ false, because multiple A resources can apply to the same name.
      break;
    case DnsType::kNs:
      new (&ns_) DnsResourceDataNs();
      time_to_live_ = kLongTimeToLive;
      cache_flush_ = true;
      break;
    case DnsType::kCName:
      new (&cname_) DnsResourceDataCName();
      time_to_live_ = kLongTimeToLive;
      cache_flush_ = true;
      break;
    case DnsType::kPtr:
      new (&ptr_) DnsResourceDataPtr();
      time_to_live_ = kLongTimeToLive;
      // cache_flush_ false, because multiple PTR resources can apply to the same name.
      break;
    case DnsType::kTxt:
      new (&txt_) DnsResourceDataTxt();
      time_to_live_ = kLongTimeToLive;
      cache_flush_ = true;
      break;
    case DnsType::kAaaa:
      new (&aaaa_) DnsResourceDataAaaa();
      time_to_live_ = kShortTimeToLive;
      // cache_flush_ false, because multiple AAAA resources can apply to the same name.
      break;
    case DnsType::kSrv:
      new (&srv_) DnsResourceDataSrv();
      time_to_live_ = kShortTimeToLive;
      cache_flush_ = true;
      break;
    case DnsType::kOpt:
      new (&opt_) DnsResourceDataOpt();
      time_to_live_ = kShortTimeToLive;
      cache_flush_ = true;
      break;
    case DnsType::kNSec:
      new (&nsec_) DnsResourceDataNSec();
      time_to_live_ = kLongTimeToLive;
      cache_flush_ = true;
      break;
    default:
      break;
  }
}

DnsResource::DnsResource(const std::string& name, inet::IpAddress address, bool cache_flush)
    : name_(DnsName(name)), cache_flush_(cache_flush) {
  if (address.is_v4()) {
    type_ = DnsType::kA;
    new (&a_) DnsResourceDataA();
    time_to_live_ = kShortTimeToLive;
    a_.address_.address_ = address;
  } else {
    type_ = DnsType::kAaaa;
    new (&aaaa_) DnsResourceDataAaaa();
    time_to_live_ = kShortTimeToLive;
    aaaa_.address_.address_ = address;
  }
}

DnsResource::DnsResource(const DnsResource& other) {
  name_ = other.name_;
  type_ = other.type_;
  class_ = other.class_;
  cache_flush_ = other.cache_flush_;
  time_to_live_ = other.time_to_live_;

  switch (type_) {
    case DnsType::kA:
      new (&a_) DnsResourceDataA();
      a_ = other.a_;
      break;
    case DnsType::kNs:
      new (&ns_) DnsResourceDataNs();
      ns_ = other.ns_;
      break;
    case DnsType::kCName:
      new (&cname_) DnsResourceDataCName();
      cname_ = other.cname_;
      break;
    case DnsType::kPtr:
      new (&ptr_) DnsResourceDataPtr();
      ptr_ = other.ptr_;
      break;
    case DnsType::kTxt:
      new (&txt_) DnsResourceDataTxt();
      txt_ = other.txt_;
      break;
    case DnsType::kAaaa:
      new (&aaaa_) DnsResourceDataAaaa();
      aaaa_ = other.aaaa_;
      break;
    case DnsType::kSrv:
      new (&srv_) DnsResourceDataSrv();
      srv_ = other.srv_;
      break;
    case DnsType::kOpt:
      new (&opt_) DnsResourceDataOpt();
      opt_ = other.opt_;
      break;
    case DnsType::kNSec:
      new (&nsec_) DnsResourceDataNSec();
      nsec_ = other.nsec_;
      break;
    default:
      break;
  }
}

DnsResource& DnsResource::operator=(const DnsResource& other) {
  name_ = other.name_;
  type_ = other.type_;
  class_ = other.class_;
  cache_flush_ = other.cache_flush_;
  time_to_live_ = other.time_to_live_;

  switch (type_) {
    case DnsType::kA:
      new (&a_) DnsResourceDataA();
      a_ = other.a_;
      break;
    case DnsType::kNs:
      new (&ns_) DnsResourceDataNs();
      ns_ = other.ns_;
      break;
    case DnsType::kCName:
      new (&cname_) DnsResourceDataCName();
      cname_ = other.cname_;
      break;
    case DnsType::kPtr:
      new (&ptr_) DnsResourceDataPtr();
      ptr_ = other.ptr_;
      break;
    case DnsType::kTxt:
      new (&txt_) DnsResourceDataTxt();
      txt_ = other.txt_;
      break;
    case DnsType::kAaaa:
      new (&aaaa_) DnsResourceDataAaaa();
      aaaa_ = other.aaaa_;
      break;
    case DnsType::kSrv:
      new (&srv_) DnsResourceDataSrv();
      srv_ = other.srv_;
      break;
    case DnsType::kOpt:
      new (&opt_) DnsResourceDataOpt();
      opt_ = other.opt_;
      break;
    case DnsType::kNSec:
      new (&nsec_) DnsResourceDataNSec();
      nsec_ = other.nsec_;
      break;
    default:
      break;
  }

  return *this;
}

DnsResource::~DnsResource() {
  switch (type_) {
    case DnsType::kA:
      a_.~DnsResourceDataA();
      break;
    case DnsType::kNs:
      ns_.~DnsResourceDataNs();
      break;
    case DnsType::kCName:
      cname_.~DnsResourceDataCName();
      break;
    case DnsType::kPtr:
      ptr_.~DnsResourceDataPtr();
      break;
    case DnsType::kTxt:
      txt_.~DnsResourceDataTxt();
      break;
    case DnsType::kAaaa:
      aaaa_.~DnsResourceDataAaaa();
      break;
    case DnsType::kSrv:
      srv_.~DnsResourceDataSrv();
      break;
    case DnsType::kOpt:
      opt_.~DnsResourceDataOpt();
      break;
    case DnsType::kNSec:
      nsec_.~DnsResourceDataNSec();
      break;
    default:
      break;
  }
}

}  // namespace mdns
