// Copyright 2019 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/devtools/protocol/background_service_handler.h"

#include "base/metrics/histogram_functions.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/render_process_host.h"

namespace content {
namespace protocol {

namespace {

devtools::proto::BackgroundService ServiceNameToEnum(
    const std::string& service_name) {
  if (service_name == BackgroundService::ServiceNameEnum::BackgroundFetch) {
    return devtools::proto::BackgroundService::BACKGROUND_FETCH;
  } else if (service_name ==
             BackgroundService::ServiceNameEnum::BackgroundSync) {
    return devtools::proto::BackgroundService::BACKGROUND_SYNC;
  } else if (service_name ==
             BackgroundService::ServiceNameEnum::PushMessaging) {
    return devtools::proto::BackgroundService::PUSH_MESSAGING;
  } else if (service_name ==
             BackgroundService::ServiceNameEnum::Notifications) {
    return devtools::proto::BackgroundService::NOTIFICATIONS;
  } else if (service_name ==
             BackgroundService::ServiceNameEnum::PaymentHandler) {
    return devtools::proto::BackgroundService::PAYMENT_HANDLER;
  } else if (service_name ==
             BackgroundService::ServiceNameEnum::PeriodicBackgroundSync) {
    return devtools::proto::BackgroundService::PERIODIC_BACKGROUND_SYNC;
  }
  return devtools::proto::BackgroundService::UNKNOWN;
}

std::string ServiceEnumToName(devtools::proto::BackgroundService service_enum) {
  switch (service_enum) {
    case devtools::proto::BackgroundService::BACKGROUND_FETCH:
      return BackgroundService::ServiceNameEnum::BackgroundFetch;
    case devtools::proto::BackgroundService::BACKGROUND_SYNC:
      return BackgroundService::ServiceNameEnum::BackgroundSync;
    case devtools::proto::BackgroundService::PUSH_MESSAGING:
      return BackgroundService::ServiceNameEnum::PushMessaging;
    case devtools::proto::BackgroundService::NOTIFICATIONS:
      return BackgroundService::ServiceNameEnum::Notifications;
    case devtools::proto::BackgroundService::PAYMENT_HANDLER:
      return BackgroundService::ServiceNameEnum::PaymentHandler;
    case devtools::proto::BackgroundService::PERIODIC_BACKGROUND_SYNC:
      return BackgroundService::ServiceNameEnum::PeriodicBackgroundSync;
    default:
      NOTREACHED();
  }

  return "invalid";
}

std::unique_ptr<protocol::Array<protocol::BackgroundService::EventMetadata>>
ProtoMapToArray(
    const google::protobuf::Map<std::string, std::string>& event_metadata_map) {
  auto metadata_array = std::make_unique<
      protocol::Array<protocol::BackgroundService::EventMetadata>>();

  for (const auto& entry : event_metadata_map) {
    auto event_metadata = protocol::BackgroundService::EventMetadata::Create()
                              .SetKey(entry.first)
                              .SetValue(entry.second)
                              .Build();
    metadata_array->emplace_back(std::move(event_metadata));
  }

  return metadata_array;
}

std::unique_ptr<protocol::BackgroundService::BackgroundServiceEvent>
ToBackgroundServiceEvent(const devtools::proto::BackgroundServiceEvent& event) {
  base::Time timestamp = base::Time::FromDeltaSinceWindowsEpoch(
      base::Microseconds(event.timestamp()));
  return protocol::BackgroundService::BackgroundServiceEvent::Create()
      .SetTimestamp(timestamp.ToJsTime() / 1'000)  // milliseconds -> seconds
      .SetOrigin(event.origin())
      .SetServiceWorkerRegistrationId(
          base::NumberToString(event.service_worker_registration_id()))
      .SetService(ServiceEnumToName(event.background_service()))
      .SetEventName(event.event_name())
      .SetInstanceId(event.instance_id())
      .SetEventMetadata(ProtoMapToArray(event.event_metadata()))
      .Build();
}

}  // namespace

BackgroundServiceHandler::BackgroundServiceHandler()
    : DevToolsDomainHandler(BackgroundService::Metainfo::domainName),
      devtools_context_(nullptr) {}

BackgroundServiceHandler::~BackgroundServiceHandler() {
  DCHECK(enabled_services_.empty());
}

void BackgroundServiceHandler::Wire(UberDispatcher* dispatcher) {
  frontend_ =
      std::make_unique<BackgroundService::Frontend>(dispatcher->channel());
  BackgroundService::Dispatcher::wire(dispatcher, this);
}

void BackgroundServiceHandler::SetRenderer(int process_host_id,
                                           RenderFrameHostImpl* frame_host) {
  RenderProcessHost* process_host = RenderProcessHost::FromID(process_host_id);
  if (!process_host) {
    if (devtools_context_ && !enabled_services_.empty())
      devtools_context_->RemoveObserver(this);
    enabled_services_.clear();
    devtools_context_ = nullptr;
    return;
  }

  auto* storage_partition =
      static_cast<StoragePartitionImpl*>(process_host->GetStoragePartition());

  if (devtools_context_) {
    DCHECK_EQ(devtools_context_,
              storage_partition->GetDevToolsBackgroundServicesContext());
    return;
  }

  devtools_context_ = static_cast<DevToolsBackgroundServicesContextImpl*>(
      storage_partition->GetDevToolsBackgroundServicesContext());
  DCHECK(devtools_context_);
}

Response BackgroundServiceHandler::Disable() {
  if (!enabled_services_.empty())
    devtools_context_->RemoveObserver(this);
  enabled_services_.clear();
  return Response::Success();
}

void BackgroundServiceHandler::StartObserving(
    const std::string& service,
    std::unique_ptr<StartObservingCallback> callback) {
  DCHECK(devtools_context_);

  auto service_enum = ServiceNameToEnum(service);
  if (service_enum == devtools::proto::BackgroundService::UNKNOWN) {
    callback->sendFailure(Response::InvalidParams("Invalid service name"));
    return;
  }

  if (enabled_services_.count(service_enum)) {
    callback->sendSuccess();
    return;
  }

  if (enabled_services_.empty())
    devtools_context_->AddObserver(this);
  enabled_services_.insert(service_enum);

  bool is_recording = devtools_context_->IsRecording(service_enum);

  DCHECK(frontend_);
  frontend_->RecordingStateChanged(is_recording, service);

  devtools_context_->GetLoggedBackgroundServiceEvents(
      service_enum,
      base::BindOnce(&BackgroundServiceHandler::DidGetLoggedEvents,
                     weak_ptr_factory_.GetWeakPtr(), service_enum,
                     std::move(callback)));
}

Response BackgroundServiceHandler::StopObserving(const std::string& service) {
  auto service_enum = ServiceNameToEnum(service);
  if (service_enum == devtools::proto::BackgroundService::UNKNOWN)
    return Response::InvalidParams("Invalid service name");

  if (!enabled_services_.count(service_enum))
    return Response::Success();

  enabled_services_.erase(service_enum);
  if (enabled_services_.empty())
    devtools_context_->RemoveObserver(this);

  return Response::Success();
}

void BackgroundServiceHandler::DidGetLoggedEvents(
    devtools::proto::BackgroundService service,
    std::unique_ptr<StartObservingCallback> callback,
    std::vector<devtools::proto::BackgroundServiceEvent> events) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // These events won't be duplicated in `OnEventReceived` since we are using
  // sequenced task runners.
  for (const auto& event : events)
    frontend_->BackgroundServiceEventReceived(ToBackgroundServiceEvent(event));

  return callback->sendSuccess();
}

Response BackgroundServiceHandler::SetRecording(bool should_record,
                                                const std::string& service) {
  DCHECK(devtools_context_);

  auto service_enum = ServiceNameToEnum(service);
  if (service_enum == devtools::proto::BackgroundService::UNKNOWN)
    return Response::InvalidParams("Invalid service name");

  if (should_record) {
    devtools_context_->StartRecording(service_enum);
    base::UmaHistogramEnumeration("DevTools.BackgroundService.StartRecording",
                                  service_enum, devtools::proto::COUNT);
  } else {
    devtools_context_->StopRecording(service_enum);
  }

  return Response::Success();
}

Response BackgroundServiceHandler::ClearEvents(const std::string& service) {
  DCHECK(devtools_context_);

  auto service_enum = ServiceNameToEnum(service);
  if (service_enum == devtools::proto::BackgroundService::UNKNOWN)
    return Response::InvalidParams("Invalid service name");

  devtools_context_->ClearLoggedBackgroundServiceEvents(service_enum);
  return Response::Success();
}

void BackgroundServiceHandler::OnEventReceived(
    const devtools::proto::BackgroundServiceEvent& event) {
  if (!enabled_services_.count(event.background_service()))
    return;

  frontend_->BackgroundServiceEventReceived(ToBackgroundServiceEvent(event));
}

void BackgroundServiceHandler::OnRecordingStateChanged(
    bool should_record,
    devtools::proto::BackgroundService service) {
  if (!enabled_services_.count(service))
    return;

  frontend_->RecordingStateChanged(should_record, ServiceEnumToName(service));
}

}  // namespace protocol
}  // namespace content
