// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/browser/service_worker_registry.h"

#include <string>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/network/network_module.h"
#include "cobalt/worker/service_worker_jobs.h"

namespace cobalt {
namespace browser {

namespace {
// Signals the given WaitableEvent.
void SignalWaitableEvent(base::WaitableEvent* event) { event->Signal(); }
}  // namespace

void ServiceWorkerRegistry::WillDestroyCurrentMessageLoop() {
  // Clear all member variables allocated form the thread.
  service_worker_jobs_.reset();
}

ServiceWorkerRegistry::ServiceWorkerRegistry(
    network::NetworkModule* network_module)
    : thread_("ServiceWorkerRegistry") {
  if (!thread_.Start()) return;
  DCHECK(message_loop());

  message_loop()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&ServiceWorkerRegistry::Initialize,
                            base::Unretained(this), network_module));

  // Register as a destruction observer to shut down the Web Agent once all
  // pending tasks have been executed and the message loop is about to be
  // destroyed. This allows us to safely stop the thread, drain the task queue,
  // then destroy the internal components before the message loop is reset.
  // No posted tasks will be executed once the thread is stopped.
  message_loop()->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&base::MessageLoop::AddDestructionObserver,
                 base::Unretained(message_loop()), base::Unretained(this)));

  // This works almost like a PostBlockingTask, except that any blocking that
  // may be necessary happens when Stop() is called instead of right now.
  message_loop()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&SignalWaitableEvent,
                            base::Unretained(&destruction_observer_added_)));
}

ServiceWorkerRegistry::~ServiceWorkerRegistry() {
  DCHECK(message_loop());
  DCHECK(thread_.IsRunning());

  // Ensure that the destruction observer got added before stopping the thread.
  // Stop the thread. This will cause the destruction observer to be notified.
  destruction_observer_added_.Wait();
  service_worker_jobs_->Stop();
  thread_.Stop();
}

worker::ServiceWorkerJobs* ServiceWorkerRegistry::service_worker_jobs() {
  // Ensure that the thread had a chance to allocate the object.
  destruction_observer_added_.Wait();
  return service_worker_jobs_.get();
}

void ServiceWorkerRegistry::Initialize(network::NetworkModule* network_module) {
  TRACE_EVENT0("cobalt::browser", "ServiceWorkerRegistry::Initialize()");
  DCHECK_EQ(base::MessageLoop::current(), message_loop());
  service_worker_jobs_.reset(
      new worker::ServiceWorkerJobs(network_module, message_loop()));
}

}  // namespace browser
}  // namespace cobalt
