// Copyright 2025 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/omnibox/omnibox_next_features.h"

#include <string>

#include "base/base64.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/autocomplete/aim_eligibility_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/grit/generated_resources.h"
#include "components/contextual_search/contextual_search_metrics_recorder.h"
#include "components/omnibox/browser/aim_eligibility_service.h"
#include "ui/base/l10n/l10n_util.h"

namespace {
constexpr base::FeatureState DISABLED = base::FEATURE_DISABLED_BY_DEFAULT;
}  // namespace

namespace omnibox {

namespace internal {

// If enabled, Omnibox popup will transition to AI-Mode with the compose-box
// panel taking up the whole of the popup, covering the location bar completely.
BASE_FEATURE(kWebUIOmniboxAimPopup, DISABLED);

}  // namespace internal

constexpr base::FeatureParam<AddContextButtonVariant>::Option
    kAddContextButtonVariantOptions[] = {
        {AddContextButtonVariant::kNone, "none"},
        {AddContextButtonVariant::kBelowResults, "below_results"},
        {AddContextButtonVariant::kAboveResults, "above_results"},
        {AddContextButtonVariant::kInline, "inline"}};

// Configures the placement of the "Add Context" button in the Omnibox popup.
const base::FeatureParam<AddContextButtonVariant>
    kWebUIOmniboxAimPopupAddContextButtonVariantParam{
        &internal::kWebUIOmniboxAimPopup, "AddContextButtonVariant",
        AddContextButtonVariant::kNone, &kAddContextButtonVariantOptions};
// If enabled, removes the cutout for the location bar and fills the entire
// popup content with the WebUI WebView.
BASE_FEATURE(kWebUIOmniboxFullPopup, DISABLED);
// If enabled, shows the omnibox suggestions in the popup in WebUI.
BASE_FEATURE(kWebUIOmniboxPopup, DISABLED);
// Enables the WebUI for omnibox suggestions without modifying the popup UI.
BASE_FEATURE(kWebUIOmniboxPopupDebug, DISABLED);
// Enables side-by-side comparison omnibox suggestions in WebUI and Views.
const base::FeatureParam<bool> kWebUIOmniboxPopupDebugSxSParam{
    &kWebUIOmniboxPopupDebug, "SxS", false};

// Decodes a proto object from its serialized Base64 string representation.
// Returns true if decoding and parsing succeed, false otherwise.
bool ParseProtoFromBase64String(const std::string& input,
                                google::protobuf::MessageLite& output) {
  if (input.empty()) {
    return false;
  }

  std::string decoded_input;
  // Decode the Base64-encoded input string into decoded_input.
  if (!base::Base64Decode(input, &decoded_input)) {
    return false;
  }

  if (decoded_input.empty()) {
    return false;
  }

  // Parse the decoded string into the proto object.
  return output.ParseFromString(decoded_input);
}

// Populates and returns the Composebox configuration proto.
omnibox::NTPComposeboxConfig GetNTPComposeboxConfig() {
  // Initialize the default config.
  omnibox::NTPComposeboxConfig default_config;
  default_config.mutable_entry_point()->set_num_page_load_animations(3);

  auto* composebox = default_config.mutable_composebox();
  composebox->set_close_by_escape(kCloseComposeboxByEscape.Get());
  composebox->set_close_by_click_outside(kCloseComposeboxByClickOutside.Get());

  auto* image_upload = composebox->mutable_image_upload();
  image_upload->set_enable_webp_encoding(false);
  image_upload->set_downscale_max_image_size(1500000);
  image_upload->set_downscale_max_image_width(1600);
  image_upload->set_downscale_max_image_height(1600);
  image_upload->set_image_compression_quality(40);
  image_upload->set_mime_types_allowed("image/*");

  auto* attachment_upload = composebox->mutable_attachment_upload();
  attachment_upload->set_max_size_bytes(200000000);
  attachment_upload->set_mime_types_allowed(".pdf,application/pdf");

  composebox->set_max_num_files(kMaxNumFiles.Get());
  composebox->set_input_placeholder_text(
      l10n_util::GetStringUTF8(IDS_NTP_COMPOSE_PLACEHOLDER_TEXT));
  composebox->set_is_pdf_upload_enabled(true);

  auto* placeholder_config = composebox->mutable_placeholder_config();
  placeholder_config->set_change_text_animation_interval_ms(4000);
  placeholder_config->set_fade_text_animation_duration_ms(250);

  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_ASK);
  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_PLAN);
  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_COMPARE);
  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_RESEARCH);
  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_TEACH);
  placeholder_config->add_placeholders(
      omnibox::NTPComposeboxConfig_PlaceholderConfig_Placeholder_WRITE);

  // Attempt to parse the config proto from the feature parameter if it is set.
  omnibox::NTPComposeboxConfig fieldtrial_config;
  if (!kConfigParam.Get().empty()) {
    bool parsed =
        ParseProtoFromBase64String(kConfigParam.Get(), fieldtrial_config);
    contextual_search::ContextualSearchMetricsRecorder::
        RecordConfigParseSuccess(
            contextual_search::ContextualSearchSource::kOmnibox, parsed);
    if (!parsed) {
      return default_config;
    }
    // A present `MimeTypesAllowed` message will clear the image and attachment
    // `mime_types` value.
    if (fieldtrial_config.composebox()
            .image_upload()
            .has_mime_types_allowed()) {
      image_upload->clear_mime_types_allowed();
    }
    if (fieldtrial_config.composebox()
            .attachment_upload()
            .has_mime_types_allowed()) {
      attachment_upload->clear_mime_types_allowed();
    }
  }

  // Merge the fieldtrial config into the default config.
  //
  // Note: The `MergeFrom()` method will append repeated fields from
  // `fieldtrial_config` to `default_config`. Since the intent is to override
  // the values of repeated fields in `default_config` with the values from
  // `fieldtrial_config`, the repeated fields in `default_config` must be
  // cleared before calling `MergeFrom()` iff the repeated fields have been set
  // in `fieldtrial_config`.
  default_config.MergeFrom(fieldtrial_config);
  return default_config;
}

bool IsAimPopupFeatureEnabled() {
  return base::FeatureList::IsEnabled(internal::kWebUIOmniboxAimPopup);
}

bool IsAimPopupEnabled(Profile* profile) {
  if (!profile) {
    return false;
  }

  if (!IsAimPopupFeatureEnabled()) {
    return false;
  }

  auto* aim_service = AimEligibilityServiceFactory::GetForProfile(profile);
  return aim_service && aim_service->IsAimEligible();
}

bool IsCreateImagesEnabled(Profile* profile) {
  if (!profile) {
    return false;
  }

  if (!IsAimPopupFeatureEnabled()) {
    return false;
  }

  if (kShowToolsAndModels.Get() && kShowCreateImageTool.Get() &&
      kForceToolsAndModels.Get()) {
    return true;
  }

  AimEligibilityService* aim_eligibility_service =
      AimEligibilityServiceFactory::GetForProfile(profile);
  return kShowToolsAndModels.Get() && kShowCreateImageTool.Get() &&
         aim_eligibility_service &&
         aim_eligibility_service->IsCreateImagesEligible();
}

bool IsDeepSearchEnabled(Profile* profile) {
  if (!profile) {
    return false;
  }

  if (!IsAimPopupFeatureEnabled()) {
    return false;
  }

  if (kShowToolsAndModels.Get() && kForceToolsAndModels.Get()) {
    return true;
  }

  AimEligibilityService* aim_eligibility_service =
      AimEligibilityServiceFactory::GetForProfile(profile);
  return kShowToolsAndModels.Get() && aim_eligibility_service &&
         aim_eligibility_service->IsDeepSearchEligible();
}

std::unique_ptr<
    contextual_search::ContextualSearchContextController::ConfigParams>
CreateQueryControllerConfigParams() {
  auto config_params = std::make_unique<
      contextual_search::ContextualSearchContextController::ConfigParams>();
  config_params->send_lns_surface = kSendLnsSurfaceParam.Get();
  config_params->suppress_lns_surface_param_if_no_image =
      kSuppressLnsSurfaceParamIfNoImage.Get();
  config_params->enable_multi_context_input_flow = kMaxNumFiles.Get() > 1;
  config_params->enable_viewport_images = kEnableViewportImages.Get();
  config_params->use_separate_request_ids_for_multi_context_viewport_images =
      kUseSeparateRequestIdsForMultiContextViewportImages.Get();
  return config_params;
}

const base::FeatureParam<bool> kCloseComposeboxByClickOutside(
    &internal::kWebUIOmniboxAimPopup,
    "CloseComposeboxByClickOutside",
    true);
const base::FeatureParam<bool> kCloseComposeboxByEscape(
    &internal::kWebUIOmniboxAimPopup,
    "CloseComposeboxByEscape",
    true);
const base::FeatureParam<std::string>
    kConfigParam(&internal::kWebUIOmniboxAimPopup, "ConfigParam", "");
const base::FeatureParam<bool> kContextMenuEnableMultiTabSelection(
    &internal::kWebUIOmniboxAimPopup,
    "ContextMenuEnableMultiTabSelection",
    false);
const base::FeatureParam<int> kContextMenuMaxTabSuggestions(
    &internal::kWebUIOmniboxAimPopup,
    "ContextMenuMaxTabSuggestions",
    5);
const base::FeatureParam<bool> kEnableViewportImages(
    &internal::kWebUIOmniboxAimPopup,
    "EnableViewportImages",
    true);
const base::FeatureParam<bool> kForceToolsAndModels(
    &internal::kWebUIOmniboxAimPopup,
    "ForceToolsAndModels",
    false);
const base::FeatureParam<int> kMaxNumFiles(&internal::kWebUIOmniboxAimPopup,
                                           "MaxNumFiles",
                                           1);
const base::FeatureParam<bool> kSendLnsSurfaceParam(
    &internal::kWebUIOmniboxAimPopup,
    "SendLnsSurfaceParam",
    true);
const base::FeatureParam<bool> kShowComposeboxImageSuggestions(
    &internal::kWebUIOmniboxAimPopup,
    "ShowComposeboxImageSuggestions",
    false);
const base::FeatureParam<bool> kShowComposeboxTypedSuggest(
    &internal::kWebUIOmniboxAimPopup,
    "ShowComposeboxTypedSuggest",
    true);
const base::FeatureParam<bool> kShowComposeboxZps(
    &internal::kWebUIOmniboxAimPopup,
    "ShowComposeboxZps",
    true);
const base::FeatureParam<bool>
    kShowContextMenu(&internal::kWebUIOmniboxAimPopup, "ShowContextMenu", true);
const base::FeatureParam<bool> kShowContextMenuDescription(
    &internal::kWebUIOmniboxAimPopup,
    "ShowContextMenuDescription",
    true);
const base::FeatureParam<bool> kShowContextMenuTabPreviews(
    &internal::kWebUIOmniboxAimPopup,
    "ShowContextMenuTabPreviews",
    true);
const base::FeatureParam<bool> kShowCreateImageTool(
    &internal::kWebUIOmniboxAimPopup,
    "ShowCreateImageTool",
    false);
const base::FeatureParam<bool> kShowRecentTabChip(
    &internal::kWebUIOmniboxAimPopup,
    "ShowRecentTabChip",
    true);
const base::FeatureParam<bool> kShowSmartCompose(
    &internal::kWebUIOmniboxAimPopup,
    "ShowSmartCompose",
    true);
const base::FeatureParam<bool> kShowSubmit(&internal::kWebUIOmniboxAimPopup,
                                           "ShowSubmit",
                                           true);
const base::FeatureParam<bool> kShowToolsAndModels(
    &internal::kWebUIOmniboxAimPopup,
    "ShowToolsAndModels",
    false);
const base::FeatureParam<bool> kSuppressLnsSurfaceParamIfNoImage(
    &internal::kWebUIOmniboxAimPopup,
    "SuppressLnsSurfaceParamIfNoImage",
    true);
const base::FeatureParam<bool>
    kUseSeparateRequestIdsForMultiContextViewportImages(
        &internal::kWebUIOmniboxAimPopup,
        "UseSeparateRequestIdsForMultiContextViewportImages",
        false);

FeatureConfig::FeatureConfig() : config(GetNTPComposeboxConfig()) {}

FeatureConfig::FeatureConfig(const FeatureConfig&) = default;
FeatureConfig::FeatureConfig(FeatureConfig&&) = default;
FeatureConfig& FeatureConfig::operator=(const FeatureConfig&) = default;
FeatureConfig& FeatureConfig::operator=(FeatureConfig&&) = default;
FeatureConfig::~FeatureConfig() = default;
}  // namespace omnibox
