// Copyright 2013 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.

#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_
#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_

#include <string>

#include "base/mac/scoped_nsobject.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/local_discovery/service_discovery_shared_client.h"
#include "content/public/browser/browser_thread.h"

namespace base {
class Thread;
}

namespace local_discovery {

template <class T>
class ServiceDiscoveryThreadDeleter {
 public:
  inline void operator()(T* t) { t->DeleteSoon(); }
};

// Implementation of ServiceDiscoveryClient that uses the Bonjour SDK.
// https://developer.apple.com/library/mac/documentation/Networking/Conceptual/
// NSNetServiceProgGuide/Articles/BrowsingForServices.html
class ServiceDiscoveryClientMac : public ServiceDiscoverySharedClient {
 public:
  ServiceDiscoveryClientMac();

 private:
  ~ServiceDiscoveryClientMac() override;

  // ServiceDiscoveryClient implementation.
  scoped_ptr<ServiceWatcher> CreateServiceWatcher(
      const std::string& service_type,
      const ServiceWatcher::UpdatedCallback& callback) override;
  scoped_ptr<ServiceResolver> CreateServiceResolver(
      const std::string& service_name,
      const ServiceResolver::ResolveCompleteCallback& callback) override;
  scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
      const std::string& domain,
      net::AddressFamily address_family,
      const LocalDomainResolver::IPAddressCallback& callback) override;

  void StartThreadIfNotStarted();

  scoped_ptr<base::Thread> service_discovery_thread_;

  DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientMac);
};

class ServiceWatcherImplMac : public ServiceWatcher {
 public:
  class NetServiceBrowserContainer {
   public:
    NetServiceBrowserContainer(
        const std::string& service_type,
        const ServiceWatcher::UpdatedCallback& callback,
        scoped_refptr<base::MessageLoopProxy> service_discovery_runner);
    ~NetServiceBrowserContainer();

    void Start();
    void DiscoverNewServices();

    void OnServicesUpdate(ServiceWatcher::UpdateType update,
                          const std::string& service);

    void DeleteSoon();

   private:
    void StartOnDiscoveryThread();
    void DiscoverOnDiscoveryThread();

    bool IsOnServiceDiscoveryThread() {
      return base::MessageLoopProxy::current() ==
             service_discovery_runner_.get();
    }

    std::string service_type_;
    ServiceWatcher::UpdatedCallback callback_;

    scoped_refptr<base::MessageLoopProxy> callback_runner_;
    scoped_refptr<base::MessageLoopProxy> service_discovery_runner_;

    base::scoped_nsobject<id> delegate_;
    base::scoped_nsobject<NSNetServiceBrowser> browser_;
    base::WeakPtrFactory<NetServiceBrowserContainer> weak_factory_;
  };

  ServiceWatcherImplMac(
      const std::string& service_type,
      const ServiceWatcher::UpdatedCallback& callback,
      scoped_refptr<base::MessageLoopProxy> service_discovery_runner);

  void OnServicesUpdate(ServiceWatcher::UpdateType update,
                        const std::string& service);

 private:
  ~ServiceWatcherImplMac() override;

  void Start() override;
  void DiscoverNewServices(bool force_update) override;
  void SetActivelyRefreshServices(bool actively_refresh_services) override;
  std::string GetServiceType() const override;

  std::string service_type_;
  ServiceWatcher::UpdatedCallback callback_;
  bool started_;

  scoped_ptr<NetServiceBrowserContainer,
             ServiceDiscoveryThreadDeleter<NetServiceBrowserContainer> >
      container_;
  base::WeakPtrFactory<ServiceWatcherImplMac> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImplMac);
};

class ServiceResolverImplMac : public ServiceResolver {
 public:
  class NetServiceContainer {
   public:
    NetServiceContainer(
        const std::string& service_name,
        const ServiceResolver::ResolveCompleteCallback& callback,
        scoped_refptr<base::MessageLoopProxy> service_discovery_runner);

    virtual ~NetServiceContainer();

    void StartResolving();

    void OnResolveUpdate(RequestStatus);

    void SetServiceForTesting(base::scoped_nsobject<NSNetService> service);

    void DeleteSoon();

   private:
    void StartResolvingOnDiscoveryThread();

    bool IsOnServiceDiscoveryThread() {
      return base::MessageLoopProxy::current() ==
             service_discovery_runner_.get();
    }

    const std::string service_name_;
    ServiceResolver::ResolveCompleteCallback callback_;

    scoped_refptr<base::MessageLoopProxy> callback_runner_;
    scoped_refptr<base::MessageLoopProxy> service_discovery_runner_;

    base::scoped_nsobject<id> delegate_;
    base::scoped_nsobject<NSNetService> service_;
    ServiceDescription service_description_;
    base::WeakPtrFactory<NetServiceContainer> weak_factory_;
  };

  ServiceResolverImplMac(
      const std::string& service_name,
      const ServiceResolver::ResolveCompleteCallback& callback,
      scoped_refptr<base::MessageLoopProxy> service_discovery_runner);

  // Testing methods.
  NetServiceContainer* GetContainerForTesting();

 private:
  ~ServiceResolverImplMac() override;

  void StartResolving() override;
  std::string GetName() const override;

  void OnResolveComplete(RequestStatus status,
                         const ServiceDescription& description);

  const std::string service_name_;
  ServiceResolver::ResolveCompleteCallback callback_;
  bool has_resolved_;

  scoped_ptr<NetServiceContainer,
             ServiceDiscoveryThreadDeleter<NetServiceContainer> > container_;
  base::WeakPtrFactory<ServiceResolverImplMac> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ServiceResolverImplMac);
};

}  // namespace local_discovery

#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_
