// 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/worker/service_worker_registration_map.h"

#include <list>
#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/script/exception_message.h"
#include "cobalt/script/promise.h"
#include "cobalt/script/script_value.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings.h"
#include "cobalt/worker/service_worker_jobs.h"
#include "cobalt/worker/service_worker_registration_object.h"
#include "cobalt/worker/service_worker_update_via_cache.h"
#include "url/gurl.h"
#include "url/origin.h"


namespace cobalt {
namespace worker {

namespace {
// Returns the serialized URL excluding the fragment.
std::string SerializeExcludingFragment(const GURL& url) {
  url::Replacements<char> replacements;
  replacements.ClearRef();
  GURL no_fragment_url = url.ReplaceComponents(replacements);
  DCHECK(!no_fragment_url.has_ref() || no_fragment_url.ref().empty());
  DCHECK(!no_fragment_url.is_empty());
  return no_fragment_url.spec();
}
}  // namespace

scoped_refptr<ServiceWorkerRegistrationObject>
ServiceWorkerRegistrationMap::MatchServiceWorkerRegistration(
    const url::Origin& storage_key, const GURL& client_url) {
  TRACE_EVENT0(
      "cobalt::worker",
      "ServiceWorkerRegistrationMap::MatchServiceWorkerRegistration()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Algorithm for Match Service Worker Registration:
  //   https://w3c.github.io/ServiceWorker/#scope-match-algorithm
  GURL matching_scope;

  // 1. Run the following steps atomically.
  {
    base::AutoLock lock(mutex_);

    // 2. Let clientURLString be serialized clientURL.
    std::string client_url_string(client_url.spec());

    // 3. Let matchingScopeString be the empty string.
    std::string matching_scope_string;

    // 4. Let scopeStringSet be an empty list.
    std::list<std::string> scope_string_set;

    // 5. For each (entry storage key, entry scope) → registration of
    // registration map:
    for (const auto& entry : registration_map_) {
      // 5.1. If storage key equals entry storage key, then append entry scope
      // to the end of scopeStringSet.
      if (entry.first.first == storage_key) {
        scope_string_set.push_back(entry.first.second);
      }
    }

    // 6. Set matchingScopeString to the longest value in scopeStringSet which
    // the value of clientURLString starts with, if it exists.
    for (const auto& scope_string : scope_string_set) {
      // TODO(b/234659851): Verify whether this is the expected behavior, where
      // a substring of the scope string is compared with the client url string.
      bool starts_with =
          client_url_string.substr(0, scope_string.length()) == scope_string;
      if (starts_with &&
          (scope_string.length() > matching_scope_string.length())) {
        matching_scope_string = scope_string;
      }
    }

    // 7. Let matchingScope be null.
    // 8. If matchingScopeString is not the empty string, then:
    if (!matching_scope_string.empty()) {
      // 8.1. Set matchingScope to the result of parsing matchingScopeString.
      matching_scope = GURL(matching_scope_string);

      // 8.2. Assert: matchingScope’s origin and clientURL’s origin are same
      // origin.
      DCHECK_EQ(url::Origin::Create(matching_scope),
                url::Origin::Create(client_url));
    }
  }

  // 9. Return the result of running Get Registration given storage key and
  // matchingScope.
  return GetRegistration(storage_key, matching_scope);
}

scoped_refptr<ServiceWorkerRegistrationObject>
ServiceWorkerRegistrationMap::GetRegistration(const url::Origin& storage_key,
                                              const GURL& scope) {
  TRACE_EVENT0("cobalt::worker",
               "ServiceWorkerRegistrationMap::GetRegistration()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Algorithm for Get Registration:
  //   https://w3c.github.io/ServiceWorker/#get-registration-algorithm

  // 1. Run the following steps atomically.
  base::AutoLock lock(mutex_);

  // 2. Let scopeString be the empty string.
  std::string scope_string;

  // 3. If scope is not null, set scopeString to serialized scope with the
  // exclude fragment flag set.
  if (!scope.is_empty()) {
    scope_string = SerializeExcludingFragment(scope);
  }

  Key registration_key(storage_key, scope_string);
  // 4. For each (entry storage key, entry scope) → registration of registration
  // map:
  for (const auto& entry : registration_map_) {
    // 4.1. If storage key equals entry storage key and scopeString matches
    // entry scope, then return registration.
    if (entry.first == registration_key) {
      return entry.second.get();
    }
  }

  // 5. Return null.
  return nullptr;
}

scoped_refptr<ServiceWorkerRegistrationObject>
ServiceWorkerRegistrationMap::SetRegistration(
    const url::Origin& storage_key, const GURL& scope,
    const ServiceWorkerUpdateViaCache& update_via_cache) {
  TRACE_EVENT0("cobalt::worker",
               "ServiceWorkerRegistrationMap::SetRegistration()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Algorithm for Set Registration:
  //   https://w3c.github.io/ServiceWorker/#set-registration-algorithm

  // 1. Run the following steps atomically.
  base::AutoLock lock(mutex_);

  // 2. Let scopeString be serialized scope with the exclude fragment flag set.
  std::string scope_string = SerializeExcludingFragment(scope);

  // 3. Let registration be a new service worker registration whose storage key
  // is set to storage key, scope url is set to scope, and update via cache mode
  // is set to updateViaCache.
  scoped_refptr<ServiceWorkerRegistrationObject> registration(
      new ServiceWorkerRegistrationObject(storage_key, scope,
                                          update_via_cache));

  // 4. Set registration map[(storage key, scopeString)] to registration.
  Key registration_key(storage_key, scope_string);
  registration_map_.insert(std::make_pair(
      registration_key,
      scoped_refptr<ServiceWorkerRegistrationObject>(registration)));

  // 5. Return registration.
  return registration;
}

void ServiceWorkerRegistrationMap::RemoveRegistration(
    const url::Origin& storage_key, const GURL& scope) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  std::string scope_string = SerializeExcludingFragment(scope);
  Key registration_key(storage_key, scope_string);
  auto entry = registration_map_.find(registration_key);
  DCHECK(entry != registration_map_.end());
  if (entry != registration_map_.end()) {
    registration_map_.erase(entry);
  }
}

bool ServiceWorkerRegistrationMap::IsUnregistered(
    ServiceWorkerRegistrationObject* registration) {
  // A service worker registration is said to be unregistered if registration
  // map[this service worker registration's (storage key, serialized scope url)]
  // is not this service worker registration.
  //   https://w3c.github.io/ServiceWorker/#dfn-service-worker-registration-unregistered
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  Key registration_key(registration->storage_key(),
                       registration->scope_url().spec());
  auto entry = registration_map_.find(registration_key);
  if (entry == registration_map_.end()) return true;

  return entry->second.get() != registration;
}

void ServiceWorkerRegistrationMap::HandleUserAgentShutdown(
    ServiceWorkerJobs* jobs) {
  TRACE_EVENT0("cobalt::worker",
               "ServiceWorkerRegistrationMap::HandleUserAgentShutdown()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Algorithm for Handle User Agent Shutdown:
  //   https://w3c.github.io/ServiceWorker/#on-user-agent-shutdown-algorithm

  // 1. For each (storage key, scope) -> registration of registration map:
  for (auto& entry : registration_map_) {
    const scoped_refptr<ServiceWorkerRegistrationObject>& registration =
        entry.second;
    // 1.1. If registration’s installing worker installingWorker is not null,
    // then:
    if (registration->installing_worker()) {
      // 1.1.1. If registration’s waiting worker is null and registration’s
      // active worker is null, invoke Clear Registration with registration and
      // continue to the next iteration of the loop.
      if (!registration->waiting_worker() && !registration->active_worker()) {
        jobs->ClearRegistration(registration);
        continue;
      } else {
        // 1.1.2. Else, set installingWorker to null.
        registration->set_installing_worker(nullptr);
      }
    }

    if (registration->waiting_worker()) {
      // 1.2. If registration’s waiting worker is not null, run the following
      // substep in parallel:

      // 1.2.1. Invoke Activate with registration.
      jobs->Activate(registration);
    }
  }
}

}  // namespace worker
}  // namespace cobalt
