// Copyright 2024 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/history_embeddings/history_embeddings_utils.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/history_embeddings/core/history_embeddings_features.h"
#include "components/optimization_guide/core/feature_registry/feature_registration.h"
#include "components/optimization_guide/core/model_execution/model_execution_prefs.h"
#include "components/optimization_guide/core/model_execution/model_execution_util.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/variations/service/variations_service.h"
#include "content/public/browser/web_ui_data_source.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/constants/chromeos_features.h"
#endif

namespace history_embeddings {

namespace {

// Returns the country code from the variations service.
std::string GetCountryCode(variations::VariationsService* variations_service) {
  std::string country_code;
  // The variations service may be nullptr in unit tests.
  if (variations_service) {
    country_code = variations_service->GetStoredPermanentCountry();
    if (country_code.empty()) {
      country_code = variations_service->GetLatestCountry();
    }
  }
  return country_code;
}

bool IsCountryAndLocale(const std::string& country, const std::string& locale) {
  return g_browser_process &&
         g_browser_process->GetApplicationLocale() == locale &&
         GetCountryCode(g_browser_process->variations_service()) == country;
}

}  // namespace

constexpr auto kEnabledByDefaultForDesktopOnly =
#if BUILDFLAG(IS_ANDROID)
    base::FEATURE_DISABLED_BY_DEFAULT;
#else
    base::FEATURE_ENABLED_BY_DEFAULT;
#endif

// These are the kill switches for the launched history embeddings features.
BASE_FEATURE(kLaunchedHistoryEmbeddings, kEnabledByDefaultForDesktopOnly);

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

  OptimizationGuideKeyedService* optimization_guide_keyed_service =
      OptimizationGuideKeyedServiceFactory::GetForProfile(profile);
  return optimization_guide_keyed_service &&
         optimization_guide_keyed_service
             ->ShouldFeatureBeCurrentlyEnabledForUser(
                 optimization_guide::UserVisibleFeatureKey::kHistorySearch);
}

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

  if (optimization_guide::
          GetGenAILocalFoundationalModelEnterprisePolicySettings(
              g_browser_process->local_state()) ==
      optimization_guide::model_execution::prefs::
          GenAILocalFoundationalModelEnterprisePolicySettings::kDisallowed) {
    return false;
  }

  OptimizationGuideKeyedService* optimization_guide_keyed_service =
      OptimizationGuideKeyedServiceFactory::GetForProfile(profile);
  return optimization_guide_keyed_service &&
         optimization_guide_keyed_service
             ->ShouldFeatureAllowModelExecutionForSignedInUser(
                 optimization_guide::UserVisibleFeatureKey::kHistorySearch);
}

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

  OptimizationGuideKeyedService* optimization_guide_keyed_service =
      OptimizationGuideKeyedServiceFactory::GetForProfile(profile);
  return optimization_guide_keyed_service &&
         optimization_guide_keyed_service->IsSettingVisible(
             optimization_guide::UserVisibleFeatureKey::kHistorySearch);
}

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

  OptimizationGuideKeyedService* optimization_guide_keyed_service =
      OptimizationGuideKeyedServiceFactory::GetForProfile(profile);
  return optimization_guide_keyed_service &&
         optimization_guide_keyed_service
             ->ShouldModelExecutionBeAllowedForUser();
}

void PopulateSourceForWebUI(content::WebUIDataSource* source,
                            Profile* profile) {
  source->AddBoolean("enableHistoryEmbeddingsAnswers",
                     IsHistoryEmbeddingsAnswersEnabledForProfile(profile));
  source->AddBoolean(
      "enableHistoryEmbeddingsImages",
      history_embeddings::GetFeatureParameters().enable_images_for_results);
  static constexpr webui::LocalizedString kHistoryEmbeddingsStrings[] = {
      {"foundSearchResults", IDS_HISTORY_FOUND_SEARCH_RESULTS},
      {"historyEmbeddingsSearchPrompt", IDS_HISTORY_EMBEDDINGS_SEARCH_PROMPT},
      {"historyEmbeddingsHeading", IDS_HISTORY_EMBEDDINGS_HEADING},
      {"historyEmbeddingsWithAnswersResultsHeading",
       IDS_HISTORY_EMBEDDINGS_WITH_ANSWERS_RESULTS_HEADING},
      {"historyEmbeddingsHeadingLoading",
       IDS_HISTORY_EMBEDDINGS_HEADING_LOADING},
      {"historyEmbeddingsFooter", IDS_HISTORY_EMBEDDINGS_FOOTER},
      {"learnMore", IDS_LEARN_MORE},
      {"thumbsUp", IDS_THUMBS_UP_RESULTS_A11Y_LABEL},
      {"thumbsDown", IDS_THUMBS_DOWN_OPENS_FEEDBACK_FORM_A11Y_LABEL},
      {"historyEmbeddingsAnswerHeading", IDS_HISTORY_EMBEDDINGS_ANSWER_HEADING},
      {"historyEmbeddingsAnswerLoadingHeading",
       IDS_HISTORY_EMBEDDINGS_ANSWER_LOADING_HEADING},
      {"historyEmbeddingsAnswerSourceDate",
       IDS_HISTORY_EMBEDDINGS_ANSWER_SOURCE_VISIT_DATE_LABEL},
      {"historyEmbeddingsAnswererErrorModelUnavailable",
       IDS_HISTORY_EMBEDDINGS_ANSWERER_ERROR_MODEL_UNAVAILABLE},
      {"historyEmbeddingsAnswererErrorTryAgain",
       IDS_HISTORY_EMBEDDINGS_ANSWERER_ERROR_TRY_AGAIN},
      {"historyEmbeddingsMatch", IDS_HISTORY_SEARCH_EMBEDDINGS_MATCH_RESULT},
      {"historyEmbeddingsMatches", IDS_HISTORY_SEARCH_EMBEDDINGS_MATCH_RESULTS},
  };
  source->AddLocalizedStrings(kHistoryEmbeddingsStrings);
  source->AddInteger("historyEmbeddingsSearchMinimumWordCount",
                     history_embeddings::GetFeatureParameters()
                         .search_query_minimum_word_count);
  source->AddString("historyEmbeddingsSettingsUrl",
                    chrome::kHistorySearchSettingURL);

  bool logging_disabled_by_enterprise =
      profile->GetPrefs()->GetInteger(
          optimization_guide::prefs::kHistorySearchEnterprisePolicyAllowed) ==
      static_cast<int>(
          optimization_guide::model_execution::prefs::
              ModelExecutionEnterprisePolicyValue::kAllowWithoutLogging);
  if (logging_disabled_by_enterprise) {
    source->AddLocalizedString("historyEmbeddingsDisclaimer",
                               IDS_HISTORY_EMBEDDINGS_DISCLAIMER_LOGGING_OFF);
  } else {
    source->AddLocalizedString("historyEmbeddingsDisclaimer",
                               IDS_HISTORY_EMBEDDINGS_DISCLAIMER);
  }
}

bool IsHistoryEmbeddingsFeatureEnabled() {
#if BUILDFLAG(IS_CHROMEOS)
  if (!chromeos::features::IsFeatureManagementHistoryEmbeddingEnabled()) {
    return false;
  }
#endif
  // If the feature is overridden manually or via Finch, return its value.
  if (base::FeatureList::GetStateIfOverridden(kHistoryEmbeddings).has_value()) {
    return base::FeatureList::IsEnabled(kHistoryEmbeddings);
  }
  // Otherwise return true for "us" and "en-US", leaving a Finch hook just in
  // case.
  return IsCountryAndLocale("us", "en-US") &&
         base::FeatureList::IsEnabled(kLaunchedHistoryEmbeddings);
}

bool IsHistoryEmbeddingsAnswersFeatureEnabled() {
  if (!IsHistoryEmbeddingsFeatureEnabled()) {
    return false;
  }
  // If the feature is overridden manually or via Finch, return its value.
  if (base::FeatureList::GetStateIfOverridden(kHistoryEmbeddingsAnswers)
          .has_value()) {
    return base::FeatureList::IsEnabled(kHistoryEmbeddingsAnswers);
  }

  return false;
}

}  // namespace history_embeddings
