// Copyright 2014 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/dns_config_watcher_mac.h"

#include <dlfcn.h>

#include "base/lazy_instance.h"
#include "third_party/apple_apsl/dnsinfo.h"

namespace {

// dnsinfo symbols are available via libSystem.dylib, but can also be present in
// SystemConfiguration.framework. To avoid confusion, load them explicitly from
// libSystem.dylib.
class DnsInfoApi {
 public:
  typedef const char* (*dns_configuration_notify_key_t)();
  typedef dns_config_t* (*dns_configuration_copy_t)();
  typedef void (*dns_configuration_free_t)(dns_config_t*);

  DnsInfoApi()
      : dns_configuration_notify_key(NULL),
        dns_configuration_copy(NULL),
        dns_configuration_free(NULL) {
    handle_ = dlopen("/usr/lib/libSystem.dylib",
                     RTLD_LAZY | RTLD_NOLOAD);
    if (!handle_)
      return;
    dns_configuration_notify_key =
        reinterpret_cast<dns_configuration_notify_key_t>(
            dlsym(handle_, "dns_configuration_notify_key"));
    dns_configuration_copy =
        reinterpret_cast<dns_configuration_copy_t>(
            dlsym(handle_, "dns_configuration_copy"));
    dns_configuration_free =
        reinterpret_cast<dns_configuration_free_t>(
            dlsym(handle_, "dns_configuration_free"));
  }

  ~DnsInfoApi() {
    if (handle_)
      dlclose(handle_);
  }

  dns_configuration_notify_key_t dns_configuration_notify_key;
  dns_configuration_copy_t dns_configuration_copy;
  dns_configuration_free_t dns_configuration_free;

 private:
  void* handle_;
};

const DnsInfoApi& GetDnsInfoApi() {
  static base::LazyInstance<DnsInfoApi>::Leaky api = LAZY_INSTANCE_INITIALIZER;
  return api.Get();
}

struct DnsConfigTDeleter {
  inline void operator()(dns_config_t* ptr) const {
    if (GetDnsInfoApi().dns_configuration_free)
      GetDnsInfoApi().dns_configuration_free(ptr);
  }
};

}  // namespace

namespace net {
namespace internal {

bool DnsConfigWatcher::Watch(
    const base::Callback<void(bool succeeded)>& callback) {
  if (!GetDnsInfoApi().dns_configuration_notify_key)
    return false;
  return watcher_.Watch(GetDnsInfoApi().dns_configuration_notify_key(),
                        callback);
}

// static
ConfigParsePosixResult DnsConfigWatcher::CheckDnsConfig() {
  if (!GetDnsInfoApi().dns_configuration_copy)
    return CONFIG_PARSE_POSIX_NO_DNSINFO;
  scoped_ptr<dns_config_t, DnsConfigTDeleter> dns_config(
      GetDnsInfoApi().dns_configuration_copy());
  if (!dns_config)
    return CONFIG_PARSE_POSIX_NO_DNSINFO;

  // TODO(szym): Parse dns_config_t for resolvers rather than res_state.
  // DnsClient can't handle domain-specific unscoped resolvers.
  unsigned num_resolvers = 0;
  for (int i = 0; i < dns_config->n_resolver; ++i) {
    dns_resolver_t* resolver = dns_config->resolver[i];
    if (!resolver->n_nameserver)
      continue;
    if (resolver->options && !strcmp(resolver->options, "mdns"))
      continue;
    ++num_resolvers;
  }
  if (num_resolvers > 1)
    return CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS;
  return CONFIG_PARSE_POSIX_OK;
}

}  // namespace internal
}  // namespace net
