// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/data_decoder/public/cpp/data_decoder.h"

#include <memory>
#include <string>
#include <utility>

#include "base/functional/callback.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "build/blink_buildflags.h"
#include "build/build_config.h"
#include "components/facilitated_payments/core/mojom/pix_code_validator.mojom.h"
#include "net/http/structured_headers.h"
#include "services/data_decoder/public/mojom/cbor_parser.mojom.h"
#include "services/data_decoder/public/mojom/gzipper.mojom.h"
#include "services/data_decoder/public/mojom/structured_headers_parser.mojom.h"
#include "services/data_decoder/public/mojom/xml_parser.mojom.h"

#if !BUILDFLAG(USE_BLINK)
#include "services/data_decoder/data_decoder_service.h"  // nogncheck
#endif

namespace data_decoder {

namespace {

// The default amount of idle time to tolerate on a DataDecoder instance. If the
// instance is unused for this period of time, the underlying service process
// (if any) may be killed and only restarted once needed again.
// On platforms (like iOS) or environments (like some unit tests) where
// out-of-process services are not used, this has no effect.
constexpr base::TimeDelta kServiceProcessIdleTimeoutDefault{base::Seconds(5)};

// Encapsulates an in-process data decoder parsing request. This provides shared
// ownership of the caller's callback so that it may be invoked exactly once by
// *either* the successful response handler *or* the parser's disconnection
// handler. This also owns a Remote<T> which is kept alive for the duration of
// the request.
template <typename T, typename V>
class ValueParseRequest : public base::RefCounted<ValueParseRequest<T, V>> {
 public:
  ValueParseRequest(DataDecoder::ResultCallback<V> callback,
                    scoped_refptr<DataDecoder::CancellationFlag> is_cancelled)
      : callback_(std::move(callback)), is_cancelled_(is_cancelled) {}

  ValueParseRequest(const ValueParseRequest&) = delete;
  ValueParseRequest& operator=(const ValueParseRequest&) = delete;

  mojo::Remote<T>& remote() { return remote_; }
  DataDecoder::ResultCallback<V>& callback() { return callback_; }

  // Creates a pipe and binds it to the remote(), and sets up the
  // disconnect handler to invoke callback() with an error.
  mojo::PendingReceiver<T> BindRemote() {
    auto receiver = remote_.BindNewPipeAndPassReceiver();
    remote_.set_disconnect_handler(
        base::BindOnce(&ValueParseRequest::OnRemoteDisconnected, this));
    return receiver;
  }

  void OnServiceValue(std::optional<V> value) {
    OnServiceValueOrError(std::move(value), std::nullopt);
  }

  // Handles a successful parse from the service.
  void OnServiceValueOrError(std::optional<V> value,
                             const std::optional<std::string>& error) {
    if (!callback() || is_cancelled_->data) {
      return;
    }

    base::expected<V, std::string> result;
    if (value) {
      result = std::move(*value);
    } else {
      result = base::unexpected(error.value_or("unknown error"));
    }

    // Copy the callback onto the stack before resetting the Remote, as that may
    // delete |this|.
    auto local_callback = std::move(callback());

    // Reset the |remote_| since we aren't using it again and we don't want it
    // to trip the disconnect handler. May delete |this|.
    remote_.reset();

    // We run the callback after reset just in case it does anything funky like
    // spin a nested RunLoop.
    std::move(local_callback).Run(std::move(result));
  }

 private:
  friend class base::RefCounted<ValueParseRequest>;

  ~ValueParseRequest() = default;

  void OnRemoteDisconnected() {
    if (is_cancelled_->data) {
      return;
    }

    if (callback()) {
      std::move(callback())
          .Run(base::unexpected("Data Decoder terminated unexpectedly"));
    }
  }

  mojo::Remote<T> remote_;
  DataDecoder::ResultCallback<V> callback_;
  scoped_refptr<DataDecoder::CancellationFlag> is_cancelled_;
};

#if !BUILDFLAG(USE_BLINK)
void BindInProcessService(
    mojo::PendingReceiver<mojom::DataDecoderService> receiver) {
  static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>>
      task_runner{base::ThreadPool::CreateSequencedTaskRunner({})};
  if (!(*task_runner)->RunsTasksInCurrentSequence()) {
    (*task_runner)
        ->PostTask(FROM_HERE,
                   base::BindOnce(&BindInProcessService, std::move(receiver)));
    return;
  }

  static base::NoDestructor<DataDecoderService> service;
  service->BindReceiver(std::move(receiver));
}
#endif

void ParsingComplete(scoped_refptr<DataDecoder::CancellationFlag> is_cancelled,
                     DataDecoder::ValueParseCallback callback,
                     base::JSONReader::Result value_with_error) {
  if (is_cancelled->data) {
    return;
  }

  if (!value_with_error.has_value()) {
    std::move(callback).Run(base::unexpected(value_with_error.error().message));
  } else {
    std::move(callback).Run(std::move(*value_with_error));
  }
}

}  // namespace

DataDecoder::DataDecoder() : DataDecoder(kServiceProcessIdleTimeoutDefault) {}

DataDecoder::DataDecoder(base::TimeDelta idle_timeout)
    : idle_timeout_(idle_timeout),
      cancel_requests_(new CancellationFlag(false)) {}

DataDecoder::~DataDecoder() {
  cancel_requests_->data = true;
}

mojom::DataDecoderService* DataDecoder::GetService() {
  // Lazily start an instance of the service if possible and necessary.
  if (!service_) {
    auto* provider = ServiceProvider::Get();
    if (provider) {
      provider->BindDataDecoderService(service_.BindNewPipeAndPassReceiver());
    } else {
#if !BUILDFLAG(USE_BLINK)
      BindInProcessService(service_.BindNewPipeAndPassReceiver());
#else
      LOG(FATAL) << "data_decoder::ServiceProvider::Set() must be called "
                 << "before any instances of DataDecoder can be used.";
#endif
    }

    service_.reset_on_disconnect();
    service_.reset_on_idle_timeout(idle_timeout_);
  }

  return service_.get();
}

void DataDecoder::ParseJson(const std::string& json,
                            ValueParseCallback callback) {
  // Measure decoding time by intercepting the callback.
  callback = base::BindOnce(
      [](base::ElapsedTimer timer, ValueParseCallback callback,
         base::expected<base::Value, std::string> result) {
        base::UmaHistogramTimes("Security.DataDecoder.Json.DecodingTime",
                                timer.Elapsed());
        std::move(callback).Run(std::move(result));
      },
      base::ElapsedTimer(), std::move(callback));

  base::JSONReader::Result result =
      base::JSONReader::ReadAndReturnValueWithError(json, base::JSON_PARSE_RFC);
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(&ParsingComplete, cancel_requests_,
                                std::move(callback), std::move(result)));
}

// static
void DataDecoder::ParseJsonIsolated(const std::string& json,
                                    ValueParseCallback callback) {
  auto decoder = std::make_unique<DataDecoder>();
  auto* raw_decoder = decoder.get();

  // We bind the DataDecoder's ownership into the result callback to ensure that
  // it stays alive until the operation is complete.
  raw_decoder->ParseJson(
      json, base::BindOnce(
                [](std::unique_ptr<DataDecoder>, ValueParseCallback callback,
                   ValueOrError result) {
                  std::move(callback).Run(std::move(result));
                },
                std::move(decoder), std::move(callback)));
}

void DataDecoder::ParseStructuredHeaderItem(
    const std::string& header,
    StructuredHeaderParseItemCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<mojom::StructuredHeadersParser,
                        net::structured_headers::ParameterizedItem>>(
      std::move(callback), cancel_requests_);
  GetService()->BindStructuredHeadersParser(request->BindRemote());
  request->remote()->ParseItem(
      header,
      base::BindOnce(
          &ValueParseRequest<
              mojom::StructuredHeadersParser,
              net::structured_headers::ParameterizedItem>::OnServiceValue,
          request));
}

// static
void DataDecoder::ParseStructuredHeaderItemIsolated(
    const std::string& header,
    StructuredHeaderParseItemCallback callback) {
  auto decoder = std::make_unique<DataDecoder>();
  auto* raw_decoder = decoder.get();

  // We bind the DataDecoder's ownership into the result callback to ensure that
  // it stays alive until the operation is complete.
  raw_decoder->ParseStructuredHeaderItem(
      header, base::BindOnce(
                  [](std::unique_ptr<DataDecoder>,
                     StructuredHeaderParseItemCallback callback,
                     base::expected<net::structured_headers::ParameterizedItem,
                                    std::string> result) {
                    std::move(callback).Run(std::move(result));
                  },
                  std::move(decoder), std::move(callback)));
}

void DataDecoder::ParseStructuredHeaderList(
    const std::string& header,
    StructuredHeaderParseListCallback callback) {
  auto request =
      base::MakeRefCounted<ValueParseRequest<mojom::StructuredHeadersParser,
                                             net::structured_headers::List>>(
          std::move(callback), cancel_requests_);
  GetService()->BindStructuredHeadersParser(request->BindRemote());
  request->remote()->ParseList(
      header,
      base::BindOnce(
          &ValueParseRequest<mojom::StructuredHeadersParser,
                             net::structured_headers::List>::OnServiceValue,
          request));
}

// static
void DataDecoder::ParseStructuredHeaderListIsolated(
    const std::string& header,
    StructuredHeaderParseListCallback callback) {
  auto decoder = std::make_unique<DataDecoder>();
  auto* raw_decoder = decoder.get();

  // We bind the DataDecoder's ownership into the result callback to ensure that
  // it stays alive until the operation is complete.
  raw_decoder->ParseStructuredHeaderList(
      header,
      base::BindOnce(
          [](std::unique_ptr<DataDecoder>,
             StructuredHeaderParseListCallback callback,
             base::expected<net::structured_headers::List, std::string>
                 result) { std::move(callback).Run(std::move(result)); },
          std::move(decoder), std::move(callback)));
}

void DataDecoder::ParseStructuredHeaderDictionary(
    const std::string& header,
    StructuredHeaderParseDictionaryCallback callback) {
  auto request = base::MakeRefCounted<ValueParseRequest<
      mojom::StructuredHeadersParser, net::structured_headers::Dictionary>>(
      std::move(callback), cancel_requests_);
  GetService()->BindStructuredHeadersParser(request->BindRemote());
  request->remote()->ParseDictionary(
      header,
      base::BindOnce(&ValueParseRequest<
                         mojom::StructuredHeadersParser,
                         net::structured_headers::Dictionary>::OnServiceValue,
                     request));
}

// static
void DataDecoder::ParseStructuredHeaderDictionaryIsolated(
    const std::string& header,
    StructuredHeaderParseDictionaryCallback callback) {
  auto decoder = std::make_unique<DataDecoder>();
  auto* raw_decoder = decoder.get();

  // We bind the DataDecoder's ownership into the result callback to ensure that
  // it stays alive until the operation is complete.
  raw_decoder->ParseStructuredHeaderDictionary(
      header,
      base::BindOnce(
          [](std::unique_ptr<DataDecoder>,
             StructuredHeaderParseDictionaryCallback callback,
             base::expected<net::structured_headers::Dictionary, std::string>
                 result) { std::move(callback).Run(std::move(result)); },
          std::move(decoder), std::move(callback)));
}

void DataDecoder::ParseXml(
    const std::string& xml,
    mojom::XmlParser::WhitespaceBehavior whitespace_behavior,
    ValueParseCallback callback) {
  auto request =
      base::MakeRefCounted<ValueParseRequest<mojom::XmlParser, base::Value>>(
          std::move(callback), cancel_requests_);
  GetService()->BindXmlParser(request->BindRemote());
  request->remote()->Parse(
      xml, whitespace_behavior,
      base::BindOnce(&ValueParseRequest<mojom::XmlParser,
                                        base::Value>::OnServiceValueOrError,
                     request));
}

// static
void DataDecoder::ParseXmlIsolated(
    const std::string& xml,
    mojom::XmlParser::WhitespaceBehavior whitespace_behavior,
    ValueParseCallback callback) {
  auto decoder = std::make_unique<DataDecoder>();
  auto* raw_decoder = decoder.get();

  // We bind the DataDecoder's ownership into the result callback to ensure that
  // it stays alive until the operation is complete.
  raw_decoder->ParseXml(
      xml, whitespace_behavior,
      base::BindOnce(
          [](std::unique_ptr<DataDecoder>, ValueParseCallback callback,
             ValueOrError result) {
            std::move(callback).Run(std::move(result));
          },
          std::move(decoder), std::move(callback)));
}

void DataDecoder::Deflate(base::span<const uint8_t> data,
                          GzipperCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>(
      std::move(callback), cancel_requests_);
  GetService()->BindGzipper(request->BindRemote());
  request->remote()->Deflate(
      data,
      base::BindOnce(&ValueParseRequest<mojom::Gzipper,
                                        mojo_base::BigBuffer>::OnServiceValue,
                     request));
}

void DataDecoder::Inflate(base::span<const uint8_t> data,
                          uint64_t max_uncompressed_size,
                          GzipperCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>(
      std::move(callback), cancel_requests_);
  GetService()->BindGzipper(request->BindRemote());
  request->remote()->Inflate(
      data, max_uncompressed_size,
      base::BindOnce(&ValueParseRequest<mojom::Gzipper,
                                        mojo_base::BigBuffer>::OnServiceValue,
                     request));
}

void DataDecoder::GzipCompress(base::span<const uint8_t> data,
                               GzipperCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>(
      std::move(callback), cancel_requests_);
  GetService()->BindGzipper(request->BindRemote());
  request->remote()->Compress(
      data,
      base::BindOnce(&ValueParseRequest<mojom::Gzipper,
                                        mojo_base::BigBuffer>::OnServiceValue,
                     request));
}

void DataDecoder::GzipUncompress(base::span<const uint8_t> data,
                                 GzipperCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<mojom::Gzipper, mojo_base::BigBuffer>>(
      std::move(callback), cancel_requests_);
  GetService()->BindGzipper(request->BindRemote());
  request->remote()->Uncompress(
      data,
      base::BindOnce(&ValueParseRequest<mojom::Gzipper,
                                        mojo_base::BigBuffer>::OnServiceValue,
                     request));
}

void DataDecoder::ParseCbor(base::span<const uint8_t> data,
                            ValueParseCallback callback) {
  auto request =
      base::MakeRefCounted<ValueParseRequest<mojom::CborParser, base::Value>>(
          std::move(callback), cancel_requests_);
  GetService()->BindCborParser(request->BindRemote());
  request->remote()->Parse(
      data,
      base::BindOnce(&ValueParseRequest<mojom::CborParser,
                                        base::Value>::OnServiceValueOrError,
                     request));
}

void DataDecoder::ValidatePixCode(const std::string& pix_code,
                                  ValidationCallback callback) {
  auto request = base::MakeRefCounted<
      ValueParseRequest<payments::facilitated::mojom::PixCodeValidator,
                        payments::facilitated::mojom::PixQrCodeType>>(
      std::move(callback), cancel_requests_);
  GetService()->BindPixCodeValidator(request->BindRemote());
  request->remote()->ValidatePixCode(
      pix_code,
      base::BindOnce(
          &ValueParseRequest<
              payments::facilitated::mojom::PixCodeValidator,
              payments::facilitated::mojom::PixQrCodeType>::OnServiceValue,
          request));
}

}  // namespace data_decoder
