// Copyright 2017 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/service_worker/service_worker_installed_scripts_sender.h"

#include "base/memory/ref_counted.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_script_cache_map.h"
#include "content/browser/service_worker/service_worker_storage.h"

namespace content {

ServiceWorkerInstalledScriptsSender::ServiceWorkerInstalledScriptsSender(
    ServiceWorkerVersion* owner)
    : owner_(owner),
      main_script_url_(owner_->script_url()),
      main_script_id_(
          owner_->script_cache_map()->LookupResourceId(main_script_url_)),
      sent_main_script_(false),
      binding_(this),
      state_(State::kNotStarted),
      last_finished_reason_(
          ServiceWorkerInstalledScriptReader::FinishedReason::kNotFinished) {
  DCHECK(ServiceWorkerVersion::IsInstalled(owner_->status()));
  DCHECK_NE(kInvalidServiceWorkerResourceId, main_script_id_);
}

ServiceWorkerInstalledScriptsSender::~ServiceWorkerInstalledScriptsSender() {}

blink::mojom::ServiceWorkerInstalledScriptsInfoPtr
ServiceWorkerInstalledScriptsSender::CreateInfoAndBind() {
  DCHECK_EQ(State::kNotStarted, state_);

  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
  owner_->script_cache_map()->GetResources(&resources);
  std::vector<GURL> installed_urls;
  for (const auto& resource : resources) {
    installed_urls.emplace_back(resource.url);
    if (resource.url == main_script_url_)
      continue;
    pending_scripts_.emplace(resource.resource_id, resource.url);
  }
  DCHECK(!installed_urls.empty())
      << "At least the main script should be installed.";

  auto info = blink::mojom::ServiceWorkerInstalledScriptsInfo::New();
  info->manager_request = mojo::MakeRequest(&manager_);
  info->installed_urls = std::move(installed_urls);
  binding_.Bind(mojo::MakeRequest(&info->manager_host_ptr));
  return info;
}

void ServiceWorkerInstalledScriptsSender::Start() {
  DCHECK_EQ(State::kNotStarted, state_);
  DCHECK_NE(kInvalidServiceWorkerResourceId, main_script_id_);
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
                                    "ServiceWorkerInstalledScriptsSender", this,
                                    "main_script_url", main_script_url_.spec());
  StartSendingScript(main_script_id_, main_script_url_);
}

void ServiceWorkerInstalledScriptsSender::StartSendingScript(
    int64_t resource_id,
    const GURL& script_url) {
  DCHECK(!reader_);
  DCHECK(current_sending_url_.is_empty());
  state_ = State::kSendingScripts;
  current_sending_url_ = script_url;

  std::unique_ptr<ServiceWorkerResponseReader> response_reader =
      owner_->context()->storage()->CreateResponseReader(resource_id);
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", "SendingScript", this,
                                    "script_url", current_sending_url_.spec());
  reader_ = std::make_unique<ServiceWorkerInstalledScriptReader>(
      std::move(response_reader), this);
  reader_->Start();
}

void ServiceWorkerInstalledScriptsSender::OnStarted(
    std::string encoding,
    base::flat_map<std::string, std::string> headers,
    mojo::ScopedDataPipeConsumerHandle body_handle,
    uint64_t body_size,
    mojo::ScopedDataPipeConsumerHandle meta_data_handle,
    uint64_t meta_data_size) {
  DCHECK(reader_);
  DCHECK_EQ(State::kSendingScripts, state_);
  TRACE_EVENT_NESTABLE_ASYNC_INSTANT2("ServiceWorker", "OnStarted", this,
                                      "body_size", body_size, "meta_data_size",
                                      meta_data_size);
  auto script_info = blink::mojom::ServiceWorkerScriptInfo::New();
  script_info->script_url = current_sending_url_;
  script_info->headers = std::move(headers);
  script_info->encoding = std::move(encoding);
  script_info->body = std::move(body_handle);
  script_info->body_size = body_size;
  script_info->meta_data = std::move(meta_data_handle);
  script_info->meta_data_size = meta_data_size;
  manager_->TransferInstalledScript(std::move(script_info));
}

void ServiceWorkerInstalledScriptsSender::OnHttpInfoRead(
    scoped_refptr<HttpResponseInfoIOBuffer> http_info) {
  DCHECK(reader_);
  DCHECK_EQ(State::kSendingScripts, state_);
  if (IsSendingMainScript())
    owner_->SetMainScriptHttpResponseInfo(*http_info->http_info);
}

void ServiceWorkerInstalledScriptsSender::OnFinished(
    ServiceWorkerInstalledScriptReader::FinishedReason reason) {
  DCHECK(reader_);
  DCHECK_EQ(State::kSendingScripts, state_);
  TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "SendingScript", this);
  reader_.reset();
  current_sending_url_ = GURL();

  if (IsSendingMainScript())
    sent_main_script_ = true;

  if (reason != ServiceWorkerInstalledScriptReader::FinishedReason::kSuccess) {
    Abort(reason);
    return;
  }

  if (pending_scripts_.empty()) {
    UpdateFinishedReasonAndBecomeIdle(
        ServiceWorkerInstalledScriptReader::FinishedReason::kSuccess);
    TRACE_EVENT_NESTABLE_ASYNC_END0(
        "ServiceWorker", "ServiceWorkerInstalledScriptsSender", this);
    return;
  }

  // Start sending the next script.
  int64_t next_id = pending_scripts_.front().first;
  GURL next_url = pending_scripts_.front().second;
  pending_scripts_.pop();
  StartSendingScript(next_id, next_url);
}

void ServiceWorkerInstalledScriptsSender::Abort(
    ServiceWorkerInstalledScriptReader::FinishedReason reason) {
  DCHECK_EQ(State::kSendingScripts, state_);
  DCHECK_NE(ServiceWorkerInstalledScriptReader::FinishedReason::kSuccess,
            reason);
  TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker",
                                  "ServiceWorkerInstalledScriptsSender", this,
                                  "FinishedReason", static_cast<int>(reason));

  // Remove all pending scripts.
  // Note that base::queue doesn't have clear(), and also base::STLClearObject
  // is not applicable for base::queue since it doesn't have reserve().
  base::queue<std::pair<int64_t, GURL>> empty;
  pending_scripts_.swap(empty);

  UpdateFinishedReasonAndBecomeIdle(reason);

  switch (reason) {
    case ServiceWorkerInstalledScriptReader::FinishedReason::kNotFinished:
    case ServiceWorkerInstalledScriptReader::FinishedReason::kSuccess:
      NOTREACHED();
      return;
    case ServiceWorkerInstalledScriptReader::FinishedReason::kNoHttpInfoError:
    case ServiceWorkerInstalledScriptReader::FinishedReason::
        kResponseReaderError:
      owner_->SetStartWorkerStatusCode(blink::SERVICE_WORKER_ERROR_DISK_CACHE);
      // Abort the worker by deleting from the registration since the data was
      // corrupted.
      if (owner_->context()) {
        ServiceWorkerRegistration* registration =
            owner_->context()->GetLiveRegistration(owner_->registration_id());
        // This ends up with destructing |this|.
        registration->DeleteVersion(owner_);
      }
      return;
    case ServiceWorkerInstalledScriptReader::FinishedReason::
        kCreateDataPipeError:
    case ServiceWorkerInstalledScriptReader::FinishedReason::kConnectionError:
    case ServiceWorkerInstalledScriptReader::FinishedReason::
        kMetaDataSenderError:
      // Notify the renderer that a connection failure happened. Usually the
      // failure means the renderer gets killed, and the error handler of
      // EmbeddedWorkerInstance is invoked soon.
      manager_.reset();
      binding_.Close();
      return;
  }
}

void ServiceWorkerInstalledScriptsSender::UpdateFinishedReasonAndBecomeIdle(
    ServiceWorkerInstalledScriptReader::FinishedReason reason) {
  DCHECK_EQ(State::kSendingScripts, state_);
  DCHECK_NE(ServiceWorkerInstalledScriptReader::FinishedReason::kNotFinished,
            reason);
  DCHECK(current_sending_url_.is_empty());
  state_ = State::kIdle;
  last_finished_reason_ = reason;
}

void ServiceWorkerInstalledScriptsSender::RequestInstalledScript(
    const GURL& script_url) {
  TRACE_EVENT1("ServiceWorker",
               "ServiceWorkerInstalledScriptsSender::RequestInstalledScript",
               "script_url", script_url.spec());
  int64_t resource_id =
      owner_->script_cache_map()->LookupResourceId(script_url);

  if (resource_id == kInvalidServiceWorkerResourceId) {
    mojo::ReportBadMessage("Requested script was not installed.");
    return;
  }

  if (state_ == State::kSendingScripts) {
    // The sender is now sending other scripts. Push the requested script into
    // the waiting queue.
    pending_scripts_.emplace(resource_id, script_url);
    return;
  }

  DCHECK_EQ(State::kIdle, state_);
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
                                    "ServiceWorkerInstalledScriptsSender", this,
                                    "main_script_url", main_script_url_.spec());
  StartSendingScript(resource_id, script_url);
}

bool ServiceWorkerInstalledScriptsSender::IsSendingMainScript() const {
  // |current_sending_url_| could match |main_script_url_| even though
  // |sent_main_script_| is false if calling importScripts for the main
  // script.
  return !sent_main_script_ && current_sending_url_ == main_script_url_;
}

}  // namespace content
