// Copyright 2019 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 "third_party/blink/renderer/modules/manifest/manifest_fetcher.h"

#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"

namespace blink {

ManifestFetcher::ManifestFetcher(const KURL& url)
    : url_(url), completed_(false) {}

ManifestFetcher::~ManifestFetcher() = default;

void ManifestFetcher::Start(LocalDOMWindow& window,
                            bool use_credentials,
                            ResourceFetcher* resource_fetcher,
                            ManifestFetcher::Callback callback) {
  callback_ = std::move(callback);

  ResourceRequest request(url_);
  request.SetRequestContext(mojom::blink::RequestContextType::MANIFEST);
  request.SetMode(network::mojom::RequestMode::kCors);
  // See https://w3c.github.io/manifest/. Use "include" when use_credentials is
  // true, and "omit" otherwise.
  request.SetCredentialsMode(use_credentials
                                 ? network::mojom::CredentialsMode::kInclude
                                 : network::mojom::CredentialsMode::kOmit);

  ResourceLoaderOptions resource_loader_options(window.GetCurrentWorld());
  resource_loader_options.data_buffering_policy = kDoNotBufferData;

  loader_ = MakeGarbageCollected<ThreadableLoader>(
      window, this, resource_loader_options, resource_fetcher);
  loader_->Start(std::move(request));
}

void ManifestFetcher::Cancel() {
  if (!loader_)
    return;

  DCHECK(!completed_);

  ThreadableLoader* loader = loader_.Release();
  loader->Cancel();
}

void ManifestFetcher::DidReceiveResponse(uint64_t,
                                         const ResourceResponse& response) {
  response_ = response;
}

void ManifestFetcher::DidReceiveData(const char* data, unsigned length) {
  if (!length)
    return;

  if (!decoder_) {
    String encoding = response_.TextEncodingName();
    decoder_ = std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
        TextResourceDecoderOptions::kPlainTextContent,
        encoding.IsEmpty() ? UTF8Encoding() : WTF::TextEncoding(encoding)));
  }

  data_.Append(decoder_->Decode(data, length));
}

void ManifestFetcher::DidFinishLoading(uint64_t) {
  DCHECK(!completed_);
  completed_ = true;

  std::move(callback_).Run(response_, data_.ToString());
  data_.Clear();
}

void ManifestFetcher::DidFail(const ResourceError& error) {
  if (!callback_)
    return;

  data_.Clear();

  std::move(callback_).Run(response_, String());
}

void ManifestFetcher::DidFailRedirectCheck() {
  DidFail(ResourceError::Failure(NullURL()));
}

void ManifestFetcher::Trace(Visitor* visitor) const {
  visitor->Trace(loader_);
  ThreadableLoaderClient::Trace(visitor);
}

}  // namespace blink
