// 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 <algorithm>
#include <string>
#include <vector>

#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"

using std::string;
using std::vector;

namespace shill {

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

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

Resolver::Resolver() {}

Resolver::~Resolver() {}

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

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

  if (dns_servers.empty() && domain_search.empty()) {
    SLOG(this, 2) << "DNS list is empty";
    return ClearDNS();
  }

  vector<string> lines;
  for (const auto& server : dns_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;
    }
  }

  vector<string> filtered_domain_search;
  for (const auto& domain : domain_search) {
    if (std::find(ignored_search_list_.begin(),
                  ignored_search_list_.end(),
                  domain) == ignored_search_list_.end()) {
      if (IsValidDNSDomain(domain)) {
        filtered_domain_search.push_back(domain);
      } else {
        LOG(WARNING) << "Malformed search domain: " << domain;
      }
    }
  }

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

  // - 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("");

  string 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::ClearDNS() {
  SLOG(this, 2) << __func__;

  CHECK(!path_.empty());

  return base::DeleteFile(path_, false);
}

}  // namespace shill
