// Copyright 2026 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/ui/webui/ai_overlay_dialog/ai_overlay_dialog_untrusted_ui.h"

#include <memory>

#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/strings/strcat.h"
#include "chrome/browser/glic/public/glic_enabling.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/ai_overlay_dialog/ai_overlay_dialog_page_handler.h"
#include "chrome/browser/ui/webui/ai_overlay_dialog/page_context_monitor.h"
#include "chrome/browser/ui/webui/ai_overlay_dialog/tools/tools.h"
#include "chrome/browser/ui/webui/webui_embedding_context.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/webui/webui_util.h"

#include "build/branding_buildflags.h"

// The grit/ generated headers are generated by the WebUI build system.
#include "chrome/grit/ai_overlay_dialog_untrusted_resources.h"
#include "chrome/grit/ai_overlay_dialog_untrusted_resources_map.h"

namespace ttc {

AiOverlayDialogUntrustedUIConfig::AiOverlayDialogUntrustedUIConfig()
    : DefaultWebUIConfig(content::kChromeUIUntrustedScheme,
                         chrome::kChromeUIAiOverlayDialogUntrustedHost) {}

bool AiOverlayDialogUntrustedUIConfig::IsWebUIEnabled(
    content::BrowserContext* browser_context) {
  return base::FeatureList::IsEnabled(features::kAiOverlayDialog) &&
         glic::GlicEnabling::IsProfileEligible(
             Profile::FromBrowserContext(browser_context));
}

AiOverlayDialogUntrustedUI::AiOverlayDialogUntrustedUI(content::WebUI* web_ui)
    : AiOverlayDialogUntrustedUIBase(web_ui
#if !BUILDFLAG(IS_ANDROID)
                                     ,
                                     /*enable_chrome_send=*/false,
                                     /*enable_chrome_histograms=*/false
#endif
      ) {
  content::WebUIDataSource* html_source =
      content::WebUIDataSource::CreateAndAdd(
          web_ui->GetWebContents()->GetBrowserContext(),
          chrome::kChromeUIAiOverlayDialogUntrustedURL);

  // TODO(crbug.com/543871096): Localize remaining Notes subpage strings.
  static constexpr webui::LocalizedString kLocalizedStrings[] = {
      {"add", IDS_ADD},
#if !BUILDFLAG(IS_ANDROID)
      {"delete", IDS_DELETE},
#else
      // TODO(crbug.com/543871096): Localize IDS_DELETE for Android, as
      // IDS_REMOVE is a generic placeholder.
      {"delete", IDS_REMOVE},
#endif  // !BUILDFLAG(IS_ANDROID)
  };
  html_source->AddLocalizedStrings(kLocalizedStrings);

  webui::SetupWebUIDataSource(
      html_source, kAiOverlayDialogUntrustedResources,
      IDR_AI_OVERLAY_DIALOG_UNTRUSTED_AI_OVERLAY_DIALOG_HTML);
  html_source->AddResourcePath(
      "notes", IDR_AI_OVERLAY_DIALOG_UNTRUSTED_NOTES_NOTES_HTML);

#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::MediaSrc,
      "media-src 'self' chrome-untrusted://resources data: blob: "
      "https://*.google.com https://*.googleusercontent.com;");
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::ConnectSrc,
      "connect-src 'self' wss://generativelanguage.googleapis.com "
      "https://*.google.com;");
#else
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::MediaSrc,
      "media-src 'self' chrome-untrusted://resources data: blob:;");
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::ConnectSrc,
      "connect-src 'self' wss://generativelanguage.googleapis.com;");
#endif

  auto* command_line = base::CommandLine::ForCurrentProcess();
  GURL ttc_bundle_url =
      GURL(command_line->GetSwitchValueASCII(switches::kTtcBundleUrl));
  if (ttc_bundle_url.is_valid()) {
    html_source->OverrideContentSecurityPolicy(
        network::mojom::CSPDirectiveName::MediaSrc,
        base::StrCat({"media-src 'self' chrome-untrusted://resources data: "
                      "blob: ",
                      ttc_bundle_url.GetWithEmptyPath().spec(), ";"}));
    html_source->OverrideContentSecurityPolicy(
        network::mojom::CSPDirectiveName::ConnectSrc,
        base::StrCat({"connect-src 'self' ",
                      "wss://generativelanguage.googleapis.com ",
                      ttc_bundle_url.GetWithEmptyPath().spec(), ";"}));
  }
  html_source->AddString(
      "ttcBundleUrl", ttc_bundle_url.is_valid() ? ttc_bundle_url.spec() : "");

  bool enable_debug_logs =
      command_line->HasSwitch(switches::kEnableTtcDebugLogs);
  html_source->AddBoolean("enableDebugLogs", enable_debug_logs);

  html_source->AddString("apiKey", features::kAiOverlayDialogApiKey.Get());
}

AiOverlayDialogUntrustedUI::~AiOverlayDialogUntrustedUI() = default;

void AiOverlayDialogUntrustedUI::BindInterface(
    mojo::PendingReceiver<ai_overlay_dialog::mojom::PageHandlerFactory>
        receiver) {
  page_handler_factory_receiver_.reset();
  page_handler_factory_receiver_.Bind(std::move(receiver));
}

void AiOverlayDialogUntrustedUI::BindInterface(
    mojo::PendingReceiver<ai_overlay_dialog::mojom::PageHandler> receiver) {
  mojo::PendingRemote<ai_overlay_dialog::mojom::Page> dummy_remote;
  page_handler_ = std::make_unique<AiOverlayDialogPageHandler>(
      std::move(receiver), std::move(dummy_remote), nullptr);
}

WEB_UI_CONTROLLER_TYPE_IMPL(AiOverlayDialogUntrustedUI)

void AiOverlayDialogUntrustedUI::CreatePageHandler(
    mojo::PendingReceiver<ai_overlay_dialog::mojom::PageHandler> receiver,
    mojo::PendingRemote<ai_overlay_dialog::mojom::Page> remote,
    mojo::PendingReceiver<ai_overlay_dialog::mojom::AiOverlayTools> tools) {
  BrowserWindowInterface* bwi =
      webui::GetBrowserWindowInterface(web_ui()->GetWebContents());
  CHECK(bwi);

  page_handler_ = std::make_unique<AiOverlayDialogPageHandler>(
      std::move(receiver), std::move(remote), bwi, this);

  page_context_monitor_ =
      std::make_unique<PageContextMonitor>(*bwi, *page_handler_);

  tools_ = std::make_unique<AiOverlayTools>(std::move(tools), bwi,
                                            page_context_monitor_.get());
}

}  // namespace ttc
