// Copyright 2018 The Chromium OS 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 "shill/resolver.h"

#include <string>
#include <vector>

#include <base/containers/contains.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_util.h>

#include "shill/dns_util.h"
#include "shill/ipconfig.h"
#include "shill/logging.h"
#include "shill/net/ip_address.h"

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kResolver;
static std::string ObjectID(const Resolver* r) {
  return "(resolver)";
}
}  // namespace Logging

const char Resolver::kDefaultIgnoredSearchList[] = "gateway.2wire.net";

Resolver::Resolver() = default;

Resolver::~Resolver() = default;

Resolver* Resolver::GetInstance() {
  static base::NoDestructor<Resolver> instance;
  return instance.get();
}

bool Resolver::SetDNSFromLists(
    const std::vector<std::string>& name_servers,
    const std::vector<std::string>& domain_search_list) {
  SLOG(this, 2) << __func__;

  name_servers_ = name_servers;
  domain_search_list_ = domain_search_list;
  return Emit();
}

bool Resolver::Emit() {
  if (path_.empty()) {
    LOG(DFATAL) << "No path set";
    return false;
  }

  // dns-proxy always used if set.
  const auto name_servers = !dns_proxy_addr_.empty()
                                ? std::vector<std::string>({dns_proxy_addr_})
                                : name_servers_;
  if (name_servers.empty() && domain_search_list_.empty()) {
    SLOG(this, 2) << "DNS list is empty";
    return ClearDNS();
  }

  std::vector<std::string> lines;
  for (const auto& server : name_servers) {
    IPAddress addr(server);
    std::string canonical_ip;
    if (addr.family() != IPAddress::kFamilyUnknown &&
        addr.IntoString(&canonical_ip)) {
      lines.push_back("nameserver " + canonical_ip);
    } else {
      LOG(WARNING) << "Malformed nameserver IP: " << server;
    }
  }

  std::vector<std::string> filtered_domain_search_list;
  for (const auto& domain : domain_search_list_) {
    if (base::Contains(ignored_search_list_, domain)) {
      continue;
    }
    if (IsValidDNSDomain(domain)) {
      filtered_domain_search_list.push_back(domain);
    } else {
      LOG(WARNING) << "Malformed search domain: " << domain;
    }
  }

  if (!filtered_domain_search_list.empty()) {
    lines.push_back("search " +
                    base::JoinString(filtered_domain_search_list, " "));
  }

  // - Send queries one-at-a-time, rather than parallelizing IPv4
  //   and IPv6 queries for a single host.
  // - Override the default 5-second request timeout and use a
  //   1-second timeout instead. (NOTE: Chrome's ADNS will use
  //   one second, regardless of what we put here.)
  // - Allow 5 attempts, rather than the default of 2.
  //   - For glibc, the worst case number of queries will be
  //        attempts * count(servers) * (count(search domains)+1)
  //   - For Chrome, the worst case number of queries will be
  //        attempts * count(servers) + 3 * glibc
  //   See crbug.com/224756 for supporting data.
  lines.push_back("options single-request timeout:1 attempts:5");

  // Newline at end of file
  lines.push_back("");

  const auto contents = base::JoinString(lines, "\n");

  SLOG(this, 2) << "Writing DNS out to " << path_.value();
  int count = base::WriteFile(path_, contents.c_str(), contents.size());

  return count == static_cast<int>(contents.size());
}

bool Resolver::SetDNSProxy(const std::string& proxy_addr) {
  SLOG(this, 2) << __func__;

  dns_proxy_addr_ = proxy_addr;
  return Emit();
}

bool Resolver::ClearDNS() {
  SLOG(this, 2) << __func__;

  if (path_.empty()) {
    LOG(DFATAL) << "No path set";
    return false;
  }

  name_servers_.clear();
  domain_search_list_.clear();
  dns_proxy_addr_.clear();
  return base::DeleteFile(path_);
}

}  // namespace shill
