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

#include <jni.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/ranges/algorithm.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/dns_probe_runner.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/browser/net/secure_dns_util.h"
#include "chrome/browser/net/stub_resolver_config_reader.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/privacy/jni_headers/SecureDnsBridge_jni.h"
#include "chrome/common/pref_names.h"
#include "components/country_codes/country_codes.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/dns/public/dns_over_https_config.h"
#include "net/dns/public/doh_provider_entry.h"
#include "net/dns/public/secure_dns_mode.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
using chrome_browser_net::DnsProbeRunner;

namespace secure_dns = chrome_browser_net::secure_dns;

namespace {

net::DohProviderEntry::List GetFilteredProviders() {
  // Note: Check whether each provider is enabled *after* filtering based on
  // country code so that if we are doing experimentation via Finch for a
  // regional provider, the experiment groups will be less likely to include
  // users from other regions unnecessarily (since a client will be included in
  // the experiment if the provider feature flag is checked).
  return secure_dns::SelectEnabledProviders(secure_dns::ProvidersForCountry(
      net::DohProviderEntry::GetList(), country_codes::GetCurrentCountryID()));
}

// Runs a DNS probe according to the configuration in |overrides|,
// asynchronously sets |success| to indicate the result, and signals
// |waiter| when the probe has completed.  Must run on the UI thread.
void RunProbe(base::WaitableEvent* waiter,
              bool* success,
              const std::string& doh_config) {
  absl::optional<net::DnsOverHttpsConfig> parsed =
      net::DnsOverHttpsConfig::FromString(doh_config);
  DCHECK(parsed.has_value());  // `doh_config` must be valid.
  auto* manager = g_browser_process->system_network_context_manager();
  auto runner = secure_dns::MakeProbeRunner(
      std::move(*parsed),
      base::BindRepeating(&SystemNetworkContextManager::GetContext,
                          base::Unretained(manager)));
  auto* const runner_ptr = runner.get();
  runner_ptr->RunProbe(base::BindOnce(
      [](base::WaitableEvent* waiter, bool* success,
         std::unique_ptr<DnsProbeRunner> runner) {
        *success = runner->result() == DnsProbeRunner::CORRECT;
        waiter->Signal();
      },
      waiter, success, std::move(runner)));
}

}  // namespace

static jint JNI_SecureDnsBridge_GetMode(JNIEnv* env) {
  return static_cast<int>(
      SystemNetworkContextManager::GetStubResolverConfigReader()
          ->GetSecureDnsConfiguration(
              true /* force_check_parental_controls_for_automatic_mode */)
          .mode());
}

static void JNI_SecureDnsBridge_SetMode(JNIEnv* env, jint mode) {
  PrefService* local_state = g_browser_process->local_state();
  local_state->SetString(
      prefs::kDnsOverHttpsMode,
      SecureDnsConfig::ModeToString(static_cast<net::SecureDnsMode>(mode)));
}

static jboolean JNI_SecureDnsBridge_IsModeManaged(JNIEnv* env) {
  PrefService* local_state = g_browser_process->local_state();
  return local_state->IsManagedPreference(prefs::kDnsOverHttpsMode);
}

static ScopedJavaLocalRef<jobjectArray> JNI_SecureDnsBridge_GetProviders(
    JNIEnv* env) {
  net::DohProviderEntry::List providers = GetFilteredProviders();
  std::vector<std::vector<std::u16string>> ret;
  ret.reserve(providers.size());
  base::ranges::transform(
      providers, std::back_inserter(ret),
      [](const auto* entry) -> std::vector<std::u16string> {
        net::DnsOverHttpsConfig config({entry->doh_server_config});
        return {base::UTF8ToUTF16(entry->ui_name),
                base::UTF8ToUTF16(config.ToString()),
                base::UTF8ToUTF16(entry->privacy_policy)};
      });
  return base::android::ToJavaArrayOfStringArray(env, ret);
}

static ScopedJavaLocalRef<jstring> JNI_SecureDnsBridge_GetConfig(JNIEnv* env) {
  PrefService* local_state = g_browser_process->local_state();
  return base::android::ConvertUTF8ToJavaString(
      env, local_state->GetString(prefs::kDnsOverHttpsTemplates));
}

static jboolean JNI_SecureDnsBridge_SetConfig(
    JNIEnv* env,
    const JavaParamRef<jstring>& jconfig) {
  PrefService* local_state = g_browser_process->local_state();
  std::string config = base::android::ConvertJavaStringToUTF8(jconfig);
  if (config.empty()) {
    local_state->ClearPref(prefs::kDnsOverHttpsTemplates);
    return true;
  }

  if (net::DnsOverHttpsConfig::FromString(config).has_value()) {
    local_state->SetString(prefs::kDnsOverHttpsTemplates, config);
    return true;
  }

  return false;
}

static jint JNI_SecureDnsBridge_GetManagementMode(JNIEnv* env) {
  return static_cast<int>(
      SystemNetworkContextManager::GetStubResolverConfigReader()
          ->GetSecureDnsConfiguration(
              true /* force_check_parental_controls_for_automatic_mode */)
          .management_mode());
}

static void JNI_SecureDnsBridge_UpdateDropdownHistograms(
    JNIEnv* env,
    const JavaParamRef<jstring>& old_config,
    const JavaParamRef<jstring>& new_config) {
  secure_dns::UpdateDropdownHistograms(
      GetFilteredProviders(),
      base::android::ConvertJavaStringToUTF8(old_config),
      base::android::ConvertJavaStringToUTF8(new_config));
}

static void JNI_SecureDnsBridge_UpdateValidationHistogram(JNIEnv* env,
                                                          jboolean valid) {
  secure_dns::UpdateValidationHistogram(valid);
}

static jboolean JNI_SecureDnsBridge_ProbeConfig(
    JNIEnv* env,
    const JavaParamRef<jstring>& doh_config) {
  // Android recommends converting async functions to blocking when using JNI:
  // https://developer.android.com/training/articles/perf-jni.
  // This function converts the DnsProbeRunner, which can only be created and
  // used on the UI thread, into a blocking function that can be called from an
  // auxiliary Java thread.
  // TODO: Use std::future if allowed in the future.
  base::WaitableEvent waiter;
  bool success;
  bool posted = content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(RunProbe, &waiter, &success,
                     base::android::ConvertJavaStringToUTF8(doh_config)));
  DCHECK(posted);
  waiter.Wait();

  secure_dns::UpdateProbeHistogram(success);
  return success;
}
