// 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 "starboard/types.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;
  std::unique_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
