// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/mdns/mdns_api.h"

#include <utility>
#include <vector>

#include "base/lazy_instance.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/api/mdns.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace extensions {

namespace mdns = api::mdns;

using DnsSdRegistry = media_router::DnsSdRegistry;

MDnsAPI::MDnsAPI(content::BrowserContext* context)
    : browser_context_(context), dns_sd_registry_(nullptr) {
  DCHECK(browser_context_);
  extensions::EventRouter* event_router = EventRouter::Get(context);
  DCHECK(event_router);
  event_router->RegisterObserver(this, mdns::OnServiceList::kEventName);
}

MDnsAPI::~MDnsAPI() = default;

// static
MDnsAPI* MDnsAPI::Get(content::BrowserContext* context) {
  return BrowserContextKeyedAPIFactory<MDnsAPI>::Get(context);
}

static base::LazyInstance<BrowserContextKeyedAPIFactory<MDnsAPI>>::
    DestructorAtExit g_mdns_api_factory = LAZY_INSTANCE_INITIALIZER;

// static
BrowserContextKeyedAPIFactory<MDnsAPI>* MDnsAPI::GetFactoryInstance() {
  return g_mdns_api_factory.Pointer();
}

void MDnsAPI::Shutdown() {
  if (dns_sd_registry_) {
    dns_sd_registry_->RemoveObserver(this);
  }
}

void MDnsAPI::SetDnsSdRegistryForTesting(DnsSdRegistry* dns_sd_registry) {
  dns_sd_registry_ = dns_sd_registry;
  if (dns_sd_registry_) {
    dns_sd_registry_->AddObserver(this);
  }
}

void MDnsAPI::ForceDiscovery() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DnsSdRegistry* registry = dns_sd_registry();
  return registry->ResetAndDiscover();
}

DnsSdRegistry* MDnsAPI::dns_sd_registry() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!dns_sd_registry_) {
    dns_sd_registry_ = media_router::DnsSdRegistry::GetInstance();
    dns_sd_registry_->AddObserver(this);
  }
  return dns_sd_registry_;
}

void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) {
  DCHECK(thread_checker_.CalledOnValidThread());
  UpdateMDnsListeners();
}

void MDnsAPI::OnListenerRemoved(const EventListenerInfo& details) {
  DCHECK(thread_checker_.CalledOnValidThread());
  UpdateMDnsListeners();
}

void MDnsAPI::UpdateMDnsListeners() {
  std::set<std::string> new_service_types;
  ServiceTypeCounts current_service_counts;
  GetValidOnServiceListListeners(
      "" /* service_type_filter - blank = all services */,
      nullptr /* extension_ids */, &current_service_counts);

  DnsSdRegistry* registry = dns_sd_registry();

  // Check if the counts of per-service-type event handlers has changed since
  // the previous invocation, and take appropriate action if a change was
  // detected.
  //
  // mDNS registration is performed for difference(cur, previous).
  // mDNS unregistration is performed for difference(previous, cur).
  // The mDNS device list is refreshed if the listener count has grown for
  // a service type in union(cur, previous).
  auto i_cur = current_service_counts.begin();
  auto i_prev = prev_service_counts_.begin();
  while (i_cur != current_service_counts.end() ||
         i_prev != prev_service_counts_.end()) {
    if (i_prev == prev_service_counts_.end() ||
        (i_cur != current_service_counts.end() &&
         i_cur->first < i_prev->first)) {
      DVLOG(2) << "Registering listener for mDNS service " << i_cur->first;
      registry->RegisterDnsSdListener(i_cur->first);
      i_cur++;
    } else if (i_cur == current_service_counts.end() ||
               (i_prev != prev_service_counts_.end() &&
                i_prev->first < i_cur->first)) {
      DVLOG(2) << "Unregistering listener for mDNS service " << i_prev->first;
      registry->UnregisterDnsSdListener(i_prev->first);
      i_prev++;
    } else {
      if (i_cur->second > i_prev->second) {
        DVLOG(2) << "Additional listeners added for mDNS service "
                 << i_cur->first;
        registry->Publish(i_cur->first);
      }
      ++i_cur;
      ++i_prev;
    }
  }
  prev_service_counts_.swap(current_service_counts);
}

void MDnsAPI::OnDnsSdEvent(const std::string& service_type,
                           const DnsSdRegistry::DnsSdServiceList& services) {
  DCHECK(thread_checker_.CalledOnValidThread());

  std::vector<mdns::MDnsService> args;
  for (const auto& service : services) {
    if (static_cast<int>(args.size()) ==
        api::mdns::MAX_SERVICE_INSTANCES_PER_EVENT) {
      // TODO(reddaly): This is not the most meaningful way of notifying the
      // application that something bad happened.  It will go to the user's
      // console (which most users don't look at)and the developer will be none
      // the wiser.  Instead, changing the event to pass the number of
      // discovered instances would allow the caller to know when the list is
      // truncated and tell the user something meaningful in the extension/app.
      WriteToConsole(
          service_type, blink::mojom::ConsoleMessageLevel::kWarning,
          base::StringPrintf("Truncating number of service instances in "
                             "onServiceList to maximum allowed: %d",
                             api::mdns::MAX_SERVICE_INSTANCES_PER_EVENT));
      break;
    }
    mdns::MDnsService mdns_service;
    mdns_service.service_name = service.service_name;
    mdns_service.service_host_port = service.service_host_port.ToString();
    mdns_service.ip_address = service.ip_address;
    mdns_service.service_data = service.service_data;
    args.push_back(std::move(mdns_service));
  }

  auto results = mdns::OnServiceList::Create(args);
  auto event = std::make_unique<Event>(events::MDNS_ON_SERVICE_LIST,
                                       mdns::OnServiceList::kEventName,
                                       std::move(results), browser_context_);
  event->filter_info->service_type = service_type;

  // TODO(justinlin): To avoid having listeners without filters getting all
  // events, modify API to have this event require filters.
  // TODO(reddaly): If event isn't on allowlist, ensure it does not get
  // broadcast to extensions.
  extensions::EventRouter::Get(browser_context_)
      ->BroadcastEvent(std::move(event));
}

const extensions::EventListenerMap::ListenerList& MDnsAPI::GetEventListeners() {
  return extensions::EventRouter::Get(browser_context_)
      ->listeners()
      .GetEventListenersByName(mdns::OnServiceList::kEventName);
}

bool MDnsAPI::IsMDnsAllowed(const ExtensionId& extension_id) const {
  const extensions::Extension* extension =
      ExtensionRegistry::Get(browser_context_)
          ->enabled_extensions()
          .GetByID(extension_id);
  return extension;
}

void MDnsAPI::GetValidOnServiceListListeners(
    const std::string& service_type_filter,
    std::set<ExtensionId>* extension_ids,
    ServiceTypeCounts* service_type_counts) {
  for (const auto& listener : GetEventListeners()) {
    const base::Value::Dict* filter = listener->filter();

    const std::string* service_type =
        filter->FindString(kEventFilterServiceTypeKey);
    if (!service_type || service_type->empty() ||
        !base::IsStringASCII(*service_type)) {
      continue;
    }

    // Match service type when filter isn't ""
    if (!service_type_filter.empty() && service_type_filter != *service_type) {
      continue;
    }

    // Don't listen for services associated only with disabled extensions.
    if (!IsMDnsAllowed(listener->extension_id())) {
      continue;
    }

    if (extension_ids) {
      extension_ids->insert(listener->extension_id());
    }
    if (service_type_counts) {
      (*service_type_counts)[*service_type]++;
    }
  }
}

void MDnsAPI::WriteToConsole(const std::string& service_type,
                             blink::mojom::ConsoleMessageLevel level,
                             const std::string& message) {
  // Get all the extensions with an onServiceList listener for a particular
  // service type.
  std::set<ExtensionId> extension_ids;
  ServiceTypeCounts counts;
  GetValidOnServiceListListeners(service_type, &extension_ids,
                                 nullptr /* service_type_counts */);

  std::string logged_message(std::string("[chrome.mdns] ") + message);

  // Log to the consoles of the background pages for those extensions.
  // TODO(devlin): It's a little weird to log to the background pages,
  // especially when it might be dormant. We should probably just log to a place
  // like the ErrorConsole instead.
  for (const ExtensionId& extension_id : extension_ids) {
    extensions::ExtensionHost* host =
        extensions::ProcessManager::Get(browser_context_)
            ->GetBackgroundHostForExtension(extension_id);
    content::RenderFrameHost* render_frame_host =
        host ? host->host_contents()->GetPrimaryMainFrame() : nullptr;
    if (render_frame_host) {
      render_frame_host->AddMessageToConsole(level, logged_message);
    }
  }
}

ExtensionFunction::ResponseAction MdnsForceDiscoveryFunction::Run() {
  MDnsAPI* api = MDnsAPI::Get(browser_context());
  if (!api) {
    return RespondNow(Error("Unknown error."));
  }
  api->ForceDiscovery();
  return RespondNow(NoArguments());
}

}  // namespace extensions
