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

#include "content/browser/renderer_host/navigation_controller_android.h"

#include <stdint.h>

#include <string>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/containers/flat_map.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "content/browser/android/additional_navigation_params_utils.h"
#include "content/browser/renderer_host/navigation_controller_impl.h"
#include "content/browser/renderer_host/navigation_entry_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/common/referrer.h"
#include "content/public/common/resource_request_body_android.h"
#include "content/public/common/url_constants.h"
#include "net/base/data_url.h"
#include "ui/gfx/android/java_bitmap.h"
#include "url/android/gurl_android.h"
#include "url/gurl.h"
#include "url/origin.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "content/public/android/content_jni_headers/NavigationControllerImpl_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF16ToJavaString;
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;

namespace {

const char kMapDataKey[] = "map_data_key";

// static
static base::android::ScopedJavaLocalRef<jobject>
JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
    JNIEnv* env,
    content::NavigationEntry* entry,
    int index) {
  DCHECK(entry);

  // Get the details of the current entry
  ScopedJavaLocalRef<jobject> j_url(
      url::GURLAndroid::FromNativeGURL(env, entry->GetURL()));
  ScopedJavaLocalRef<jobject> j_virtual_url(
      url::GURLAndroid::FromNativeGURL(env, entry->GetVirtualURL()));
  ScopedJavaLocalRef<jobject> j_original_url(
      url::GURLAndroid::FromNativeGURL(env, entry->GetOriginalRequestURL()));
  ScopedJavaLocalRef<jstring> j_title(
      ConvertUTF16ToJavaString(env, entry->GetTitle()));
  ScopedJavaLocalRef<jobject> j_bitmap;
  const content::FaviconStatus& status = entry->GetFavicon();
  if (status.valid && status.image.ToSkBitmap()->computeByteSize() > 0) {
    j_bitmap = gfx::ConvertToJavaBitmap(*status.image.ToSkBitmap(),
                                        gfx::OomBehavior::kReturnNullOnOom);
  }
  jlong j_timestamp = entry->GetTimestamp().InMillisecondsSinceUnixEpoch();

  return content::Java_NavigationControllerImpl_createNavigationEntry(
      env, index, j_url, j_virtual_url, j_original_url, j_title, j_bitmap,
      entry->GetTransitionType(), j_timestamp, entry->IsInitialEntry());
}

static void JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
    JNIEnv* env,
    const JavaRef<jobject>& history,
    content::NavigationEntry* entry,
    int index) {
  content::Java_NavigationControllerImpl_addToNavigationHistory(
      env, history,
      JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
                                                             index));
}

class MapData : public base::SupportsUserData::Data {
 public:
  MapData() = default;

  MapData(const MapData&) = delete;
  MapData& operator=(const MapData&) = delete;

  ~MapData() override = default;

  static MapData* Get(content::NavigationEntry* entry) {
    MapData* map_data = static_cast<MapData*>(entry->GetUserData(kMapDataKey));
    if (map_data)
      return map_data;
    auto map_data_ptr = std::make_unique<MapData>();
    map_data = map_data_ptr.get();
    entry->SetUserData(kMapDataKey, std::move(map_data_ptr));
    return map_data;
  }

  base::flat_map<std::string, std::u16string>& map() { return map_; }

  // base::SupportsUserData::Data:
  std::unique_ptr<Data> Clone() override {
    std::unique_ptr<MapData> clone = std::make_unique<MapData>();
    clone->map_ = map_;
    return clone;
  }

 private:
  base::flat_map<std::string, std::u16string> map_;
};

}  // namespace

namespace content {

NavigationControllerAndroid::NavigationControllerAndroid(
    NavigationControllerImpl* navigation_controller)
    : navigation_controller_(navigation_controller) {
  JNIEnv* env = AttachCurrentThread();
  obj_.Reset(env, Java_NavigationControllerImpl_create(
                      env, reinterpret_cast<intptr_t>(this)));
}

NavigationControllerAndroid::~NavigationControllerAndroid() {
  Java_NavigationControllerImpl_destroy(AttachCurrentThread(), obj_);
}

base::android::ScopedJavaLocalRef<jobject>
NavigationControllerAndroid::GetJavaObject() {
  return base::android::ScopedJavaLocalRef<jobject>(obj_);
}

jboolean NavigationControllerAndroid::CanGoBack(JNIEnv* env) {
  return navigation_controller_->CanGoBack();
}

jboolean NavigationControllerAndroid::CanGoForward(JNIEnv* env) {
  return navigation_controller_->CanGoForward();
}

jboolean NavigationControllerAndroid::CanGoToOffset(JNIEnv* env, jint offset) {
  return navigation_controller_->CanGoToOffsetWithSkipping(offset);
}

void NavigationControllerAndroid::GoBack(JNIEnv* env) {
  navigation_controller_->GoBack();
}

void NavigationControllerAndroid::GoForward(JNIEnv* env) {
  navigation_controller_->GoForward();
}

void NavigationControllerAndroid::GoToOffset(JNIEnv* env,
                                             jint offset) {
  navigation_controller_->GoToOffsetWithSkipping(offset);
}

jboolean NavigationControllerAndroid::IsInitialNavigation(JNIEnv* env) {
  return navigation_controller_->IsInitialNavigation();
}

void NavigationControllerAndroid::LoadIfNecessary(JNIEnv* env) {
  navigation_controller_->LoadIfNecessary();
}

void NavigationControllerAndroid::ContinuePendingReload(JNIEnv* env) {
  navigation_controller_->ContinuePendingReload();
}

void NavigationControllerAndroid::Reload(JNIEnv* env,
                                         jboolean check_for_repost) {
  SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "Reload_check",
                        (bool)check_for_repost);
  navigation_controller_->Reload(ReloadType::NORMAL, check_for_repost);
}

void NavigationControllerAndroid::ReloadBypassingCache(
    JNIEnv* env,
    jboolean check_for_repost) {
  SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "ReloadB_check",
                        (bool)check_for_repost);
  navigation_controller_->Reload(ReloadType::BYPASSING_CACHE, check_for_repost);
}

jboolean NavigationControllerAndroid::NeedsReload(JNIEnv* env) {
  return navigation_controller_->NeedsReload();
}

void NavigationControllerAndroid::SetNeedsReload(JNIEnv* env) {
  navigation_controller_->SetNeedsReload();
}

void NavigationControllerAndroid::CancelPendingReload(JNIEnv* env) {
  navigation_controller_->CancelPendingReload();
}

void NavigationControllerAndroid::GoToNavigationIndex(JNIEnv* env, jint index) {
  navigation_controller_->GoToIndex(index);
}

base::android::ScopedJavaLocalRef<jobject> NavigationControllerAndroid::LoadUrl(
    JNIEnv* env,
    const JavaParamRef<jstring>& url,
    jint load_url_type,
    jint transition_type,
    const JavaParamRef<jstring>& j_referrer_url,
    jint referrer_policy,
    jint ua_override_option,
    const JavaParamRef<jstring>& extra_headers,
    const JavaParamRef<jobject>& j_post_data,
    const JavaParamRef<jstring>& base_url_for_data_url,
    const JavaParamRef<jstring>& virtual_url_for_special_cases,
    const JavaParamRef<jstring>& data_url_as_string,
    jboolean can_load_local_resources,
    jboolean is_renderer_initiated,
    jboolean should_replace_current_entry,
    const JavaParamRef<jobject>& j_initiator_origin,
    jboolean has_user_gesture,
    jboolean should_clear_history_list,
    const base::android::JavaParamRef<jobject>& j_additional_navigation_params,
    jlong input_start,
    jlong navigation_ui_data_ptr,
    jboolean is_pdf) {
  DCHECK(url);
  NavigationController::LoadURLParams params(
      GURL(ConvertJavaStringToUTF8(env, url)));
  // Wrap the raw pointer in case on an early return.
  std::unique_ptr<NavigationUIData> navigation_ui_data = base::WrapUnique(
      reinterpret_cast<NavigationUIData*>(navigation_ui_data_ptr));
  params.load_type =
      static_cast<NavigationController::LoadURLType>(load_url_type);
  params.transition_type = ui::PageTransitionFromInt(transition_type);
  params.override_user_agent =
      static_cast<NavigationController::UserAgentOverrideOption>(
          ua_override_option);
  params.can_load_local_resources = can_load_local_resources;
  params.is_renderer_initiated = is_renderer_initiated;
  params.should_replace_current_entry = should_replace_current_entry;
  params.has_user_gesture = has_user_gesture;
  params.should_clear_history_list = should_clear_history_list;
  params.is_pdf = is_pdf;

  if (j_additional_navigation_params) {
    params.initiator_frame_token =
        GetInitiatorFrameTokenFromJavaAdditionalNavigationParams(
            env, j_additional_navigation_params);
    params.initiator_process_id =
        GetInitiatorProcessIdFromJavaAdditionalNavigationParams(
            env, j_additional_navigation_params);

    // If the attribution src token exists, then an impression exists with this
    // navigation.
    if (std::optional<blink::AttributionSrcToken> attribution_src_token =
            GetAttributionSrcTokenFromJavaAdditionalNavigationParams(
                env, j_additional_navigation_params)) {
      params.impression = blink::Impression{
          .attribution_src_token = *attribution_src_token,
      };
    }
  }

  if (extra_headers)
    params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);

  params.post_data = ExtractResourceRequestBodyFromJavaObject(env, j_post_data);

  if (base_url_for_data_url) {
    params.base_url_for_data_url =
        GURL(ConvertJavaStringToUTF8(env, base_url_for_data_url));
  }

  if (virtual_url_for_special_cases) {
    params.virtual_url_for_special_cases =
        GURL(ConvertJavaStringToUTF8(env, virtual_url_for_special_cases));
  }

  if (data_url_as_string) {
    // Treat |data_url_as_string| as if we were intending to put it into a GURL
    // field. Note that kMaxURLChars is only enforced when serializing URLs
    // for IPC.
    GURL data_url = GURL(ConvertJavaStringToUTF8(env, data_url_as_string));
    DCHECK(data_url.SchemeIs(url::kDataScheme));
    DCHECK(params.url.SchemeIs(url::kDataScheme));
#if DCHECK_IS_ON()
    {
      std::string mime_type, charset, data;
      DCHECK(net::DataURL::Parse(params.url, &mime_type, &charset, &data));
      DCHECK(data.empty());
    }
#endif
    std::string s = data_url.spec();
    params.data_url_as_string =
        base::MakeRefCounted<base::RefCountedString>(std::move(s));
  }

  if (j_referrer_url) {
    params.referrer =
        Referrer(GURL(ConvertJavaStringToUTF8(env, j_referrer_url)),
                 Referrer::ConvertToPolicy(referrer_policy));
  }

  if (j_initiator_origin) {
    params.initiator_origin =
        url::Origin::FromJavaObject(env, j_initiator_origin);
  }

  if (input_start != 0)
    params.input_start = base::TimeTicks::FromUptimeMillis(input_start);

  params.navigation_ui_data = std::move(navigation_ui_data);

  base::WeakPtr<NavigationHandle> handle =
      navigation_controller_->LoadURLWithParams(params);

  if (!handle) {
    return nullptr;
  }

  return base::android::ScopedJavaLocalRef<jobject>(
      handle->GetJavaNavigationHandle());
}

void NavigationControllerAndroid::ClearHistory(JNIEnv* env) {
  // TODO(creis): Do callers of this need to know if it fails?
  if (navigation_controller_->CanPruneAllButLastCommitted())
    navigation_controller_->PruneAllButLastCommitted();
}

jint NavigationControllerAndroid::GetNavigationHistory(
    JNIEnv* env,
    const JavaParamRef<jobject>& history) {
  // Iterate through navigation entries to populate the list
  int count = navigation_controller_->GetEntryCount();
  for (int i = 0; i < count; ++i) {
    JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
        env, history, navigation_controller_->GetEntryAtIndex(i), i);
  }

  return navigation_controller_->GetCurrentEntryIndex();
}

void NavigationControllerAndroid::GetDirectedNavigationHistory(
    JNIEnv* env,
    const JavaParamRef<jobject>& history,
    jboolean is_forward,
    jint max_entries) {
  // Iterate through navigation entries to populate the list
  int count = navigation_controller_->GetEntryCount();
  int num_added = 0;
  int increment_value = is_forward ? 1 : -1;
  for (int i = navigation_controller_->GetCurrentEntryIndex() + increment_value;
       i >= 0 && i < count; i += increment_value) {
    if (num_added >= max_entries)
      break;

    JNI_NavigationControllerImpl_AddNavigationEntryToHistory(
        env, history, navigation_controller_->GetEntryAtIndex(i), i);
    num_added++;
  }
}

void NavigationControllerAndroid::ClearSslPreferences(JNIEnv* env) {
  SSLHostStateDelegate* delegate =
      navigation_controller_->GetBrowserContext()->GetSSLHostStateDelegate();
  if (delegate)
    delegate->Clear(base::NullCallback());
}

bool NavigationControllerAndroid::GetUseDesktopUserAgent(JNIEnv* env) {
  NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry();
  return entry && entry->GetIsOverridingUserAgent();
}

void NavigationControllerAndroid::SetUseDesktopUserAgent(
    JNIEnv* env,
    jboolean enabled,
    jboolean reload_on_state_change,
    jint source) {
  SCOPED_CRASH_KEY_BOOL("nav_reentrancy_caller2", "SetUA_enabled",
                        (bool)enabled);
  if (GetUseDesktopUserAgent(env) == enabled) {
    return;
  }

  if (navigation_controller_->in_navigate_to_pending_entry() &&
      reload_on_state_change) {
    // Sometimes it's possible to call this function in response to a
    // navigation to a pending entry. In this case, we should avoid triggering
    // another navigation synchronously, as it will crash due to navigation
    // re-entrancy checks. To do that, post a task to update the UA and
    // reload asynchronously.
    // TODO(crbug.com/40841494): Figure out the case that leads to this
    // situation and avoid calling this function entirely in that case. For now,
    // do a do a DumpWithoutCrashing so that we can investigate.
    GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE,
        base::BindOnce(
            &NavigationControllerAndroid::SetUseDesktopUserAgentInternal,
            weak_factory_.GetWeakPtr(), enabled, reload_on_state_change));
    LOG(WARNING) << "NavigationControllerAndroid::SetUseDesktopUserAgent "
                 << "triggers re-entrant navigation, override: "
                 << (bool)enabled << ", source: " << (int)source;
    SCOPED_CRASH_KEY_NUMBER("SetUseDesktopUserAgent", "caller", (int)source);
    base::debug::DumpWithoutCrashing();
  } else {
    SetUseDesktopUserAgentInternal(enabled, reload_on_state_change);
  }
}

void NavigationControllerAndroid::SetUseDesktopUserAgentInternal(
    bool enabled,
    bool reload_on_state_change) {
  // Make sure the navigation entry actually exists.
  NavigationEntry* entry = navigation_controller_->GetLastCommittedEntry();
  // TODO(crbug.com/40063008): Early return for initial NavigationEntries as a
  // workaround. Currently, doing a reload while on the initial NavigationEntry
  // might result in committing an unrelated pending NavigationEntry and
  // mistakenly marking that entry as an initial NavigationEntry. That will
  // cause problems, such as the URL bar showing about:blank instead of the URL
  // of the NavigationEntry. To prevent that happening in this case, skip
  // reloading initial NavigationEntries entirely. This is a short-term fix,
  // while we work on a long-term fix to no longer mistakenly mark the unrelated
  // pending NavigationEntry as the initial NavigationEntry.
  if (!entry || entry->IsInitialEntry()) {
    return;
  }

  // Set the flag in the NavigationEntry.
  entry->SetIsOverridingUserAgent(enabled);
  navigation_controller_->delegate()->UpdateOverridingUserAgent();

  // Send the override to the renderer.
  if (reload_on_state_change) {
    // Reloading the page will send the override down as part of the
    // navigation IPC message.
    navigation_controller_->LoadOriginalRequestURL();
  }
}

base::android::ScopedJavaLocalRef<jobject>
NavigationControllerAndroid::GetEntryAtIndex(JNIEnv* env,
                                             int index) {
  if (index < 0 || index >= navigation_controller_->GetEntryCount())
    return base::android::ScopedJavaLocalRef<jobject>();

  NavigationEntry* entry = navigation_controller_->GetEntryAtIndex(index);
  return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
                                                                index);
}

base::android::ScopedJavaLocalRef<jobject>
NavigationControllerAndroid::GetVisibleEntry(JNIEnv* env) {
  NavigationEntry* entry = navigation_controller_->GetVisibleEntry();

  if (!entry)
    return base::android::ScopedJavaLocalRef<jobject>();

  return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(env, entry,
                                                                /*index=*/-1);
}

base::android::ScopedJavaLocalRef<jobject>
NavigationControllerAndroid::GetPendingEntry(JNIEnv* env) {
  NavigationEntry* entry = navigation_controller_->GetPendingEntry();

  if (!entry)
    return base::android::ScopedJavaLocalRef<jobject>();

  return JNI_NavigationControllerImpl_CreateJavaNavigationEntry(
      env, entry, navigation_controller_->GetPendingEntryIndex());
}

jint NavigationControllerAndroid::GetLastCommittedEntryIndex(JNIEnv* env) {
  return navigation_controller_->GetLastCommittedEntryIndex();
}

jboolean NavigationControllerAndroid::CanViewSource(JNIEnv* env) {
  return navigation_controller_->CanViewSource();
}

jboolean NavigationControllerAndroid::RemoveEntryAtIndex(JNIEnv* env,
                                                         jint index) {
  return navigation_controller_->RemoveEntryAtIndex(index);
}

void NavigationControllerAndroid::PruneForwardEntries(JNIEnv* env) {
  return navigation_controller_->PruneForwardEntries();
}

ScopedJavaLocalRef<jstring> NavigationControllerAndroid::GetEntryExtraData(
    JNIEnv* env,
    jint index,
    const JavaParamRef<jstring>& jkey) {
  if (index < 0 || index >= navigation_controller_->GetEntryCount())
    return ScopedJavaLocalRef<jstring>();

  std::string key = base::android::ConvertJavaStringToUTF8(env, jkey);
  MapData* map_data =
      MapData::Get(navigation_controller_->GetEntryAtIndex(index));
  auto iter = map_data->map().find(key);
  return ConvertUTF16ToJavaString(
      env, iter == map_data->map().end() ? std::u16string() : iter->second);
}

void NavigationControllerAndroid::SetEntryExtraData(
    JNIEnv* env,
    jint index,
    const JavaParamRef<jstring>& jkey,
    const JavaParamRef<jstring>& jvalue) {
  if (index < 0 || index >= navigation_controller_->GetEntryCount())
    return;

  std::string key = base::android::ConvertJavaStringToUTF8(env, jkey);
  std::u16string value = base::android::ConvertJavaStringToUTF16(env, jvalue);
  MapData* map_data =
      MapData::Get(navigation_controller_->GetEntryAtIndex(index));
  map_data->map()[key] = value;
}

void NavigationControllerAndroid::CopyStateFrom(
    JNIEnv* env,
    jlong source_navigation_controller_ptr,
    jboolean needs_reload) {
  navigation_controller_->CopyStateFrom(
      reinterpret_cast<NavigationControllerAndroid*>(
          source_navigation_controller_ptr)
          ->navigation_controller_,
      needs_reload);
}

}  // namespace content
