// 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 "chrome/browser/extensions/api/gcm/gcm_api.h"

#include <stddef.h>

#include <algorithm>
#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/extensions/extension_gcm_app_handler.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/gcm.h"
#include "components/gcm_driver/common/gcm_message.h"
#include "components/gcm_driver/gcm_client.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/gcm_driver/gcm_profile_service.h"
#include "extensions/browser/event_router.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace {

const size_t kMaximumGcmMessageSize = 4096;  // in bytes.
const char kCollapseKey[] = "collapse_key";
const char kGoogDotRestrictedPrefix[] = "goog.";
const char kGoogleRestrictedPrefix[] = "google";

// Error messages.
const char kInvalidParameter[] =
    "Function was called with invalid parameters.";
const char kGCMDisabled[] = "GCM is currently disabled.";
const char kAsyncOperationPending[] =
    "Asynchronous operation is pending.";
const char kNetworkError[] = "Network error occurred.";
const char kServerError[] = "Server error occurred.";
const char kTtlExceeded[] = "Time-to-live exceeded.";
const char kUnknownError[] = "Unknown error occurred.";

const char* GcmResultToError(gcm::GCMClient::Result result) {
  switch (result) {
    case gcm::GCMClient::SUCCESS:
      return "";
    case gcm::GCMClient::INVALID_PARAMETER:
      return kInvalidParameter;
    case gcm::GCMClient::GCM_DISABLED:
      return kGCMDisabled;
    case gcm::GCMClient::ASYNC_OPERATION_PENDING:
      return kAsyncOperationPending;
    case gcm::GCMClient::NETWORK_ERROR:
      return kNetworkError;
    case gcm::GCMClient::SERVER_ERROR:
      return kServerError;
    case gcm::GCMClient::TTL_EXCEEDED:
      return kTtlExceeded;
    case gcm::GCMClient::UNKNOWN_ERROR:
      return kUnknownError;
    default:
      NOTREACHED() << "Unexpected value of result cannot be converted: "
                   << result;
  }
}

bool IsMessageKeyValid(const std::string& key) {
  std::string lower = base::ToLowerASCII(key);
  return !key.empty() &&
         key.compare(0, std::size(kCollapseKey) - 1, kCollapseKey) != 0 &&
         lower.compare(0, std::size(kGoogleRestrictedPrefix) - 1,
                       kGoogleRestrictedPrefix) != 0 &&
         lower.compare(0, std::size(kGoogDotRestrictedPrefix),
                       kGoogDotRestrictedPrefix) != 0;
}

}  // namespace

namespace extensions {

bool GcmApiFunction::PreRunValidation(std::string* error) {
  return IsGcmApiEnabled(error);
}

bool GcmApiFunction::IsGcmApiEnabled(std::string* error) const {
  Profile* profile = Profile::FromBrowserContext(browser_context());

  // GCM is not supported in incognito mode.
  if (profile->IsOffTheRecord()) {
    *error = "GCM is not supported in incognito mode.";
    return false;
  }

  return true;
}

gcm::GCMDriver* GcmApiFunction::GetGCMDriver() const {
  return gcm::GCMProfileServiceFactory::GetForProfile(
      Profile::FromBrowserContext(browser_context()))->driver();
}

GcmRegisterFunction::GcmRegisterFunction() = default;

GcmRegisterFunction::~GcmRegisterFunction() = default;

ExtensionFunction::ResponseAction GcmRegisterFunction::Run() {
  std::optional<api::gcm::Register::Params> params =
      api::gcm::Register::Params::Create(args());
  EXTENSION_FUNCTION_VALIDATE(params);

#if BUILDFLAG(IS_ANDROID)
  // This server API was deprecated by Firebase in 2019. Don't bother trying to
  // implement register() on Android - it will just return an error.
  // TODO(crbug.com/421235963): Consider deprecating on other platforms.
  return RespondNow(Error(GcmResultToError(gcm::GCMClient::UNKNOWN_ERROR)));
#else
  GetGCMDriver()->Register(
      extension()->id(), params->sender_ids,
      base::BindOnce(&GcmRegisterFunction::CompleteFunctionWithResult, this));

  // Register() might have returned synchronously.
  return did_respond() ? AlreadyResponded() : RespondLater();
#endif  // BUILDFLAG(IS_ANDROID)
}

void GcmRegisterFunction::CompleteFunctionWithResult(
    const std::string& registration_id,
    gcm::GCMClient::Result gcm_result) {
  base::Value::List result;
  result.Append(registration_id);

  const bool succeeded = gcm::GCMClient::SUCCESS == gcm_result;
  Respond(succeeded
              ? ArgumentList(std::move(result))
              // TODO(lazyboy): We shouldn't be using |result| in case of error.
              : ErrorWithArgumentsDoNotUse(std::move(result),
                                           GcmResultToError(gcm_result)));
}

GcmUnregisterFunction::GcmUnregisterFunction() = default;

GcmUnregisterFunction::~GcmUnregisterFunction() = default;

ExtensionFunction::ResponseAction GcmUnregisterFunction::Run() {
#if BUILDFLAG(IS_ANDROID)
  // This server API was deprecated by Firebase in 2019. Don't bother trying to
  // implement register() on Android - it will just return an error.
  // TODO(crbug.com/421235963): Consider deprecating on other platforms.
  return RespondNow(Error(GcmResultToError(gcm::GCMClient::UNKNOWN_ERROR)));
#else
  GetGCMDriver()->Unregister(
      extension()->id(),
      base::BindOnce(&GcmUnregisterFunction::CompleteFunctionWithResult, this));

  // Unregister might have responded already (synchronously).
  return did_respond() ? AlreadyResponded() : RespondLater();
#endif  // BUILDFLAG(IS_ANDROID)
}

void GcmUnregisterFunction::CompleteFunctionWithResult(
    gcm::GCMClient::Result result) {
  const bool succeeded = gcm::GCMClient::SUCCESS == result;
  Respond(succeeded ? NoArguments() : Error(GcmResultToError(result)));
}

GcmSendFunction::GcmSendFunction() = default;

GcmSendFunction::~GcmSendFunction() = default;

ExtensionFunction::ResponseAction GcmSendFunction::Run() {
  std::optional<api::gcm::Send::Params> params =
      api::gcm::Send::Params::Create(args());
  EXTENSION_FUNCTION_VALIDATE(params);
  EXTENSION_FUNCTION_VALIDATE(
      ValidateMessageData(params->message.data.additional_properties));

  gcm::OutgoingMessage outgoing_message;
  outgoing_message.id = params->message.message_id;
  outgoing_message.data = params->message.data.additional_properties;
  if (params->message.time_to_live)
    outgoing_message.time_to_live = *params->message.time_to_live;

  GetGCMDriver()->Send(
      extension()->id(), params->message.destination_id, outgoing_message,
      base::BindOnce(&GcmSendFunction::CompleteFunctionWithResult, this));

  // Send might have already responded synchronously.
  return did_respond() ? AlreadyResponded() : RespondLater();
}

void GcmSendFunction::CompleteFunctionWithResult(
    const std::string& message_id,
    gcm::GCMClient::Result gcm_result) {
  base::Value::List result;
  result.Append(message_id);

  const bool succeeded = gcm::GCMClient::SUCCESS == gcm_result;
  Respond(succeeded
              ? ArgumentList(std::move(result))
              // TODO(lazyboy): We shouldn't be using |result| in case of error.
              : ErrorWithArgumentsDoNotUse(std::move(result),
                                           GcmResultToError(gcm_result)));
}

bool GcmSendFunction::ValidateMessageData(const gcm::MessageData& data) const {
  size_t total_size = 0u;
  for (const auto& [key, value] : data) {
    total_size += key.size() + value.size();

    if (!IsMessageKeyValid(key) || kMaximumGcmMessageSize < key.size() ||
        kMaximumGcmMessageSize < value.size() ||
        kMaximumGcmMessageSize < total_size)
      return false;
  }

  return total_size != 0;
}

GcmJsEventRouter::GcmJsEventRouter(Profile* profile) : profile_(profile) {
}

GcmJsEventRouter::~GcmJsEventRouter() = default;

void GcmJsEventRouter::OnMessage(const std::string& app_id,
                                 const gcm::IncomingMessage& message) {
  api::gcm::OnMessage::Message message_arg;
  message_arg.data.additional_properties = message.data;
  if (!message.sender_id.empty())
    message_arg.from = message.sender_id;
  if (!message.collapse_key.empty()) {
    message_arg.collapse_key = message.collapse_key;
  }

  std::unique_ptr<Event> event(
      new Event(events::GCM_ON_MESSAGE, api::gcm::OnMessage::kEventName,
                api::gcm::OnMessage::Create(message_arg), profile_));
  EventRouter::Get(profile_)
      ->DispatchEventToExtension(app_id, std::move(event));
}

void GcmJsEventRouter::OnMessagesDeleted(const std::string& app_id) {
  std::unique_ptr<Event> event(new Event(
      events::GCM_ON_MESSAGES_DELETED, api::gcm::OnMessagesDeleted::kEventName,
      api::gcm::OnMessagesDeleted::Create(), profile_));
  EventRouter::Get(profile_)
      ->DispatchEventToExtension(app_id, std::move(event));
}

void GcmJsEventRouter::OnSendError(
    const std::string& app_id,
    const gcm::GCMClient::SendErrorDetails& send_error_details) {
  api::gcm::OnSendError::Error error;
  error.message_id = send_error_details.message_id;
  error.error_message = GcmResultToError(send_error_details.result);
  error.details.additional_properties = send_error_details.additional_data;

  std::unique_ptr<Event> event(
      new Event(events::GCM_ON_SEND_ERROR, api::gcm::OnSendError::kEventName,
                api::gcm::OnSendError::Create(error), profile_));
  EventRouter::Get(profile_)
      ->DispatchEventToExtension(app_id, std::move(event));
}

}  // namespace extensions
