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

#include "components/cast_receiver/browser/application_client.h"

#include "base/supports_user_data.h"
#include "components/media_control/browser/media_blocker.h"
#include "components/url_rewrite/browser/url_request_rewrite_rules_manager.h"
#include "components/url_rewrite/common/url_loader_throttle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"

namespace cast_receiver {
namespace {

// Key in the WebContents's UserData here the instance for a given WebContents
// is stored.
const char kApplicationControlsUserDataKey[] =
    "components/cast_receiver/browser/application_client";

// Helper function to call the method on each observer
template <typename TObserver, typename TFunc, typename... TArgs>
void NotifyObservers(base::ObserverList<TObserver>& observers,
                     TFunc&& func,
                     TArgs&&... args) {
  for (auto& observer : observers) {
    (observer.*func)(args...);
  }
}

// This class acts as a wrapper around WebContents-specific classes, acting on
// them based on changes to it. Specifically, it handles connection of any
// cross-process mojo APIs.
class ApplicationControlsImpl : public ApplicationClient::ApplicationControls,
                                public base::SupportsUserData::Data {
 public:
  explicit ApplicationControlsImpl(content::WebContents& web_contents)
      : web_contents_(web_contents), media_blocker_(&web_contents) {
    url_request_rewrite_rules_manager_.AddWebContents(&web_contents);
  }
  ~ApplicationControlsImpl() override {
    url_request_rewrite_rules_manager_.RemoveWebContents(&*web_contents_);
  }

  media_control::MediaBlocker& GetMediaBlocker() override {
    return media_blocker_;
  }

  url_rewrite::UrlRequestRewriteRulesManager& GetUrlRequestRewriteRulesManager()
      override {
    return url_request_rewrite_rules_manager_;
  }

 private:
  const raw_ref<content::WebContents> web_contents_;
  media_control::MediaBlocker media_blocker_;
  url_rewrite::UrlRequestRewriteRulesManager url_request_rewrite_rules_manager_;
};

}  // namespace

ApplicationClient::ApplicationControls::~ApplicationControls() = default;

ApplicationClient::ApplicationClient(
    network::NetworkContextGetter network_context_getter)
    : network_context_getter_(std::move(network_context_getter)),
      weak_factory_(this) {}

ApplicationClient::~ApplicationClient() = default;

void ApplicationClient::AddApplicationStateObserver(
    ApplicationStateObserver* observer) {
  application_state_observer_list_.AddObserver(observer);
}

void ApplicationClient::RemoveApplicationStateObserver(
    ApplicationStateObserver* observer) {
  application_state_observer_list_.RemoveObserver(observer);
}

void ApplicationClient::OnWebContentsCreated(
    content::WebContents* web_contents) {
  DCHECK(web_contents);
  web_contents->SetUserData(
      &kApplicationControlsUserDataKey,
      std::make_unique<ApplicationControlsImpl>(*web_contents));
}

std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
ApplicationClient::CreateURLLoaderThrottles(
    const base::RepeatingCallback<content::WebContents*()>& wc_getter,
    content::FrameTreeNodeId frame_tree_node_id,
    CorsExemptHeaderCallback is_cors_exempt_header_cb) {
  std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
  if (frame_tree_node_id.is_null()) {
    return throttles;
  }

  content::WebContents* web_contents = wc_getter.Run();
  if (web_contents) {
    const auto& rules = GetApplicationControls(*web_contents)
                            .GetUrlRequestRewriteRulesManager()
                            .GetCachedRules();
    if (rules) {
      throttles.emplace_back(std::make_unique<url_rewrite::URLLoaderThrottle>(
          rules, std::move(is_cors_exempt_header_cb)));
    }
  }
  return throttles;
}

void ApplicationClient::OnForegroundApplicationChanged(
    RuntimeApplication* app) {
  NotifyObservers(application_state_observer_list_,
                  &ApplicationStateObserver::OnForegroundApplicationChanged,
                  app);
}

ApplicationClient::ApplicationControls&
ApplicationClient::GetApplicationControls(
    const content::WebContents& web_contents) {
  ApplicationControlsImpl* instance = static_cast<ApplicationControlsImpl*>(
      web_contents.GetUserData(&kApplicationControlsUserDataKey));
  DCHECK(instance);
  return *instance;
}

}  // namespace cast_receiver
