// 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();
  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
