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

#include "content/browser/notifications/notification_storage.h"

#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "content/browser/notifications/notification_database_data_conversions.h"

namespace content {

namespace {

// Schema is as follows:
// KEY: NOTIFICATION_<|data.notification_id|>
// VALUE: <serialized content::proto::NotificationDatabaseData>

const char kNotificationPrefix[] = "NOTIFICATION_";

// Create the key that will be used for the service worker database.
std::string CreateDataKey(const std::string& notification_id) {
  DCHECK(!notification_id.empty());
  return kNotificationPrefix + notification_id;
}

// Updates the time of the last click on the notification, and the first if
// necessary.
void UpdateNotificationClickTimestamps(NotificationDatabaseData* data) {
  base::TimeDelta delta = base::Time::Now() - data->creation_time_millis;
  if (!data->time_until_first_click_millis.has_value())
    data->time_until_first_click_millis = delta;
  data->time_until_last_click_millis = delta;
}

}  // namespace

NotificationStorage::NotificationStorage(
    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
    : service_worker_context_(std::move(service_worker_context)),
      weak_ptr_factory_(this) {}

NotificationStorage::~NotificationStorage() = default;

void NotificationStorage::WriteNotificationData(
    const NotificationDatabaseData& data,
    const PlatformNotificationContext::WriteResultCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  std::string serialized_data;
  if (!SerializeNotificationDatabaseData(data, &serialized_data)) {
    DLOG(ERROR) << "Unable to serialize data for a notification belonging "
                << "to: " << data.origin;
    callback.Run(/* success= */ false, std::string());
    return;
  }

  service_worker_context_->StoreRegistrationUserData(
      data.service_worker_registration_id, data.origin,
      {{CreateDataKey(data.notification_id), std::move(serialized_data)}},
      base::BindOnce(&NotificationStorage::OnWriteComplete,
                     weak_ptr_factory_.GetWeakPtr(), data, callback));
}

void NotificationStorage::OnWriteComplete(
    const NotificationDatabaseData& data,
    const PlatformNotificationContext::WriteResultCallback& callback,
    blink::ServiceWorkerStatusCode status) {
  if (status == blink::ServiceWorkerStatusCode::kOk) {
    callback.Run(/* success= */ true, data.notification_id);
  } else {
    callback.Run(/* success= */ false,
                 /* notification_id= */ std::string());
  }
}

void NotificationStorage::ReadNotificationDataAndRecordInteraction(
    int64_t service_worker_registration_id,
    const std::string& notification_id,
    PlatformNotificationContext::Interaction interaction,
    const PlatformNotificationContext::ReadResultCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  service_worker_context_->GetRegistrationUserData(
      service_worker_registration_id, {CreateDataKey(notification_id)},
      base::BindOnce(&NotificationStorage::OnReadCompleteUpdateInteraction,
                     weak_ptr_factory_.GetWeakPtr(),
                     service_worker_registration_id, interaction, callback));
}

void NotificationStorage::OnReadCompleteUpdateInteraction(
    int64_t service_worker_registration_id,
    PlatformNotificationContext::Interaction interaction,
    const PlatformNotificationContext::ReadResultCallback& callback,
    const std::vector<std::string>& database_data,
    blink::ServiceWorkerStatusCode status) {
  if (status != blink::ServiceWorkerStatusCode::kOk || database_data.empty()) {
    callback.Run(/* success= */ false, NotificationDatabaseData());
    return;
  }

  auto data = std::make_unique<NotificationDatabaseData>();
  if (!DeserializeNotificationDatabaseData(database_data[0], data.get())) {
    DLOG(ERROR) << "Unable to deserialize data for a notification belonging "
                << "to: " << data->origin;
    callback.Run(/* success= */ false, NotificationDatabaseData());
    return;
  }

  switch (interaction) {
    case PlatformNotificationContext::Interaction::CLOSED:
      data->time_until_close_millis =
          base::Time::Now() - data->creation_time_millis;
      break;
    case PlatformNotificationContext::Interaction::NONE:
      break;
    case PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED:
      data->num_action_button_clicks += 1;
      UpdateNotificationClickTimestamps(data.get());
      break;
    case PlatformNotificationContext::Interaction::CLICKED:
      data->num_clicks += 1;
      UpdateNotificationClickTimestamps(data.get());
      break;
  }
  std::string serialized_data;
  if (!SerializeNotificationDatabaseData(*data, &serialized_data)) {
    DLOG(ERROR) << "Unable to serialize data for a notification belonging "
                << "to: " << data->origin;
    callback.Run(/* success= */ false, NotificationDatabaseData());
    return;
  }

  GURL origin = data->origin;
  std::string notification_id = data->notification_id;
  service_worker_context_->StoreRegistrationUserData(
      service_worker_registration_id, origin,
      {{CreateDataKey(notification_id), std::move(serialized_data)}},
      base::BindOnce(&NotificationStorage::OnInteractionUpdateComplete,
                     weak_ptr_factory_.GetWeakPtr(), std::move(data),
                     callback));
}

void NotificationStorage::OnInteractionUpdateComplete(
    std::unique_ptr<NotificationDatabaseData> data,
    const PlatformNotificationContext::ReadResultCallback& callback,
    blink::ServiceWorkerStatusCode status) {
  DCHECK(data);
  if (status == blink::ServiceWorkerStatusCode::kOk)
    callback.Run(/* success= */ true, *data);
  else
    callback.Run(/* success= */ false, NotificationDatabaseData());
}

}  // namespace content
