// 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 "chrome/browser/feed/android/feed_service_bridge.h"

#include <vector>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/feed/feed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/feed/core/shared_prefs/pref_names.h"
#include "components/feed/core/v2/config.h"
#include "components/feed/core/v2/public/feed_service.h"
#include "components/feed/core/v2/public/stream_type.h"
#include "components/feed/feed_feature_list.h"
#include "components/metrics/metrics_service.h"
#include "components/prefs/pref_service.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "chrome/browser/feed/android/jni_headers/FeedServiceBridge_jni.h"

namespace feed {
namespace {

FeedService* GetFeedService() {
  Profile* profile = ProfileManager::GetLastUsedProfile();
  if (!profile)
    return nullptr;
  return FeedServiceFactory::GetForBrowserContext(profile);
}

FeedApi* GetFeedApi() {
  FeedService* service = GetFeedService();
  if (!service)
    return nullptr;
  return service->GetStream();
}

}  // namespace

static jboolean JNI_FeedServiceBridge_IsEnabled(JNIEnv* env) {
  return FeedServiceBridge::IsEnabled();
}

static void JNI_FeedServiceBridge_Startup(JNIEnv* env) {
  // Trigger creation FeedService, since we need to handle certain browser
  // events, like sign-in/sign-out, even if the Feed isn't visible.
  GetFeedService();
}

static int JNI_FeedServiceBridge_GetLoadMoreTriggerLookahead(JNIEnv* env) {
  return GetFeedConfig().load_more_trigger_lookahead;
}

static int JNI_FeedServiceBridge_GetLoadMoreTriggerScrollDistanceDp(
    JNIEnv* env) {
  return GetFeedConfig().load_more_trigger_scroll_distance_dp;
}

static jlong JNI_FeedServiceBridge_GetReliabilityLoggingId(JNIEnv* env) {
  return FeedServiceBridge::GetReliabilityLoggingId();
}

static jlong JNI_FeedServiceBridge_AddUnreadContentObserver(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& j_observer,
    jboolean is_web_feed) {
  FeedApi* api = GetFeedApi();
  if (!api)
    return static_cast<jint>(ContentOrder::kUnspecified);
  JavaUnreadContentObserver* observer = new JavaUnreadContentObserver(
      base::android::ScopedJavaGlobalRef<jobject>(j_observer));
  api->AddUnreadContentObserver(is_web_feed ? StreamType(StreamKind::kFollowing)
                                            : StreamType(StreamKind::kForYou),
                                observer);
  return reinterpret_cast<jlong>(observer);
}

static void JNI_FeedServiceBridge_ReportOtherUserActionForStream(
    JNIEnv* env,
    jint stream_kind,
    jint action) {
  FeedApi* api = GetFeedApi();
  if (!api)
    return;
  api->ReportOtherUserAction(StreamType(static_cast<StreamKind>(stream_kind)),
                             static_cast<FeedUserActionType>(action));
}

static void JNI_FeedServiceBridge_ReportOtherUserAction(JNIEnv* env,
                                                        jint action) {
  FeedApi* api = GetFeedApi();
  if (!api) {
    return;
  }
  api->ReportOtherUserAction(static_cast<FeedUserActionType>(action));
}

static jint JNI_FeedServiceBridge_GetContentOrderForWebFeed(JNIEnv* env) {
  FeedApi* api = GetFeedApi();
  if (!api)
    return 0;
  return static_cast<int>(
      api->GetContentOrder(StreamType(StreamKind::kFollowing)));
}

static void JNI_FeedServiceBridge_SetContentOrderForWebFeed(
    JNIEnv* env,
    jint content_order) {
  FeedApi* api = GetFeedApi();
  if (!api)
    return;
  switch (content_order) {
    case static_cast<jint>(ContentOrder::kGrouped):
      api->SetContentOrder(StreamType(StreamKind::kFollowing),
                           ContentOrder::kGrouped);
      return;
    case static_cast<jint>(ContentOrder::kReverseChron):
      api->SetContentOrder(StreamType(StreamKind::kFollowing),
                           ContentOrder::kReverseChron);
      return;
    case static_cast<jint>(ContentOrder::kUnspecified):
      break;
  }
  NOTREACHED() << "Invalid content order: " << content_order;
}

static jboolean JNI_FeedServiceBridge_IsSignedIn(JNIEnv* env) {
  return FeedServiceBridge::IsSignedIn();
}

std::string FeedServiceBridge::GetLanguageTag() {
  JNIEnv* env = base::android::AttachCurrentThread();
  return Java_FeedServiceBridge_getLanguageTag(env);
}

DisplayMetrics FeedServiceBridge::GetDisplayMetrics() {
  JNIEnv* env = base::android::AttachCurrentThread();
  std::vector<double> numbers;
  base::android::JavaDoubleArrayToDoubleVector(
      env, Java_FeedServiceBridge_getDisplayMetrics(env), &numbers);
  DCHECK_EQ(3UL, numbers.size());
  DisplayMetrics result;
  result.density = numbers[0];
  result.width_pixels = numbers[1];
  result.height_pixels = numbers[2];
  return result;
}

void FeedServiceBridge::ClearAll() {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_FeedServiceBridge_clearAll(env);
}

bool FeedServiceBridge::IsEnabled() {
  Profile* profile = ProfileManager::GetLastUsedProfile();
  return FeedService::IsEnabled(*profile->GetPrefs());
}

void FeedServiceBridge::PrefetchImage(const GURL& url) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_FeedServiceBridge_prefetchImage(env, url.spec());
}

uint64_t FeedServiceBridge::GetReliabilityLoggingId() {
  PrefService* profile_prefs = ProfileManager::GetLastUsedProfile()->GetPrefs();
  if (!g_browser_process->metrics_service()) {
    // If for some reason we don't have the metrics client ID, an ID based only
    // on the random "salt" will be generated.
    return FeedService::GetReliabilityLoggingId(/*metrics_id=*/std::string(),
                                                profile_prefs);
  }
  return FeedService::GetReliabilityLoggingId(
      g_browser_process->metrics_service()->GetClientId(), profile_prefs);
}

// static
bool FeedServiceBridge::IsSignedIn() {
  return GetFeedService()->IsSignedIn();
}

JavaUnreadContentObserver::JavaUnreadContentObserver(
    base::android::ScopedJavaGlobalRef<jobject> j_observer)
    : obj_(j_observer) {}

feed::JavaUnreadContentObserver::~JavaUnreadContentObserver() = default;

void JavaUnreadContentObserver::HasUnreadContentChanged(
    bool has_unread_content) {
  JNIEnv* env = base::android::AttachCurrentThread();
  Java_UnreadContentObserver_hasUnreadContentChanged(env, obj_,
                                                     has_unread_content);
}

void JavaUnreadContentObserver::Destroy(JNIEnv*) {
  delete this;
}

}  // namespace feed
