// 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.

#ifndef SERVICES_DATA_DECODER_PUBLIC_CPP_DATA_DECODER_H_
#define SERVICES_DATA_DECODER_PUBLIC_CPP_DATA_DECODER_H_

#include <optional>
#include <string>

#include "base/functional/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/http/structured_headers.h"
#include "services/data_decoder/public/cpp/service_provider.h"
#include "services/data_decoder/public/mojom/data_decoder_service.mojom.h"
#include "services/data_decoder/public/mojom/xml_parser.mojom.h"

namespace mojo_base {
class BigBuffer;
}

namespace data_decoder {

// IMPORTANT: Before adding something, please consider if there is a viable
// memory-safe implementation; the data decoder is already a grab bag of random
// stuff and process startup time can be a major performance tax, especially on
// mobile.
//
// Encapsulates an exclusive connection to an isolated instance of the Data
// Decoder service, allowing an owner to perform a series of related decoding
// operations using the same isolated instance. The application must provide
// an instance of |ServiceProvider| via |ServiceProvider::Set()| prior to using
// this class.
//
// In general, instance reuse should only be considered after weighing the cost
// of new service processes vs the security and privacy value of increased
// isolation.
//
// Finally, there is no guarantee that a single DataDecoder instance will
// perform all out-of-process operations within the same service process; if
// idle for long periods of time, the service process may be killed and only
// restarted once needed again.
//
// Tests can construct an data_decoder::test::InProcessDataDecoderService to
// ensure that all DataDecoders constructed during its lifetime will connect to
// that instance rather than launching a separate process.
class DataDecoder {
 public:
  // Creates a DataDecoder with an implementation-defined default timeout.
  DataDecoder();
  // Creates a DataDecoder with the specified timeout.
  explicit DataDecoder(base::TimeDelta idle_timeout);

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

  ~DataDecoder();

  using ValueOrError = base::expected<base::Value, std::string>;
  template <typename T>
  using ResultCallback =
      base::OnceCallback<void(base::expected<T, std::string>)>;
  using StructuredHeaderParseItemCallback =
      ResultCallback<net::structured_headers::ParameterizedItem>;
  using StructuredHeaderParseListCallback =
      ResultCallback<net::structured_headers::List>;
  using StructuredHeaderParseDictionaryCallback =
      ResultCallback<net::structured_headers::Dictionary>;
  using ValueParseCallback = ResultCallback<base::Value>;
  using GzipperCallback = ResultCallback<mojo_base::BigBuffer>;
  using ValidationCallback =
      ResultCallback<payments::facilitated::mojom::PixQrCodeType>;
  using CancellationFlag = base::RefCountedData<bool>;

  // Returns a raw interface to the service instance. This launches an instance
  // of the service process if possible on the current platform, or returns a
  // connection to the in-process instance of in a test environment using
  // InProcessDataDecoderService.
  mojom::DataDecoderService* GetService();

  // Parses the potentially unsafe JSON string in |json| using this
  // DataDecoder's service instance or some other platform-specific decoding
  // facility. The parser conforms to RFC 8259.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseJson(const std::string& json, ValueParseCallback callback);

  // Parses the potentially unsafe JSON string in |json|. This static helper
  // uses a dedicated instance of the Data Decoder service on applicable
  // platforms.
  static void ParseJsonIsolated(const std::string& json,
                                ValueParseCallback callback);

  // Parses the potentially unsafe string in |header| as a structured header
  // item using this DataDecoder's service instance or some other
  // platform-specific decoding facility.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseStructuredHeaderItem(const std::string& header,
                                 StructuredHeaderParseItemCallback callback);

  // Parses the potentially unsafe string in |header| as a structured header
  // item. This static helper uses a dedicated instance of the Data Decoder
  // service on applicable platforms.
  static void ParseStructuredHeaderItemIsolated(
      const std::string& header,
      StructuredHeaderParseItemCallback callback);

  // Parses the potentially unsafe string in |header| as a structured header
  // list using this DataDecoder's service instance or some other
  // platform-specific decoding facility.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseStructuredHeaderList(const std::string& header,
                                 StructuredHeaderParseListCallback callback);

  // Parses the potentially unsafe string in |header| as a structured header
  // list. This static helper uses a dedicated instance of the Data Decoder
  // service on applicable platforms.
  static void ParseStructuredHeaderListIsolated(
      const std::string& header,
      StructuredHeaderParseListCallback callback);

  // Parses the potentially unsafe string in `header` as a structured header
  // dictionary using this DataDecoder's service instance or some other
  // platform-specific decoding facility.
  //
  // Note that `callback` will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseStructuredHeaderDictionary(
      const std::string& header,
      StructuredHeaderParseDictionaryCallback callback);

  // Parses the potentially unsafe string in `header` as a structured header
  // dictionary. This static helper uses a dedicated instance of the Data
  // Decoder service on applicable platforms.
  static void ParseStructuredHeaderDictionaryIsolated(
      const std::string& header,
      StructuredHeaderParseDictionaryCallback callback);

  // Parses the potentially unsafe XML string in |xml| using this
  // DataDecoder's service instance. The Value provided to the callback
  // is a structured tree representing the XML document. See
  // ../mojom/xml_parser.mojom for details on the structure, and
  // safe_xml_parser.h for utilities to access parsed data.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseXml(const std::string& xml,
                mojom::XmlParser::WhitespaceBehavior whitespace_behavior,
                ValueParseCallback callback);

  // Parses the potentially unsafe XML string in |xml|. This static helper
  // uses a dedicated instance of the Data Decoder service on applicable
  // platforms.
  static void ParseXmlIsolated(
      const std::string& xml,
      mojom::XmlParser::WhitespaceBehavior whitespace_behavior,
      ValueParseCallback callback);

  // Deflates potentially unsafe |data| using this DataDecoder's service
  // instance. This will use raw DEFLATE, i.e. no headers are outputted.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void Deflate(base::span<const uint8_t> data, GzipperCallback callback);

  // Inflates potentially unsafe |data| using this DataDecoder's service
  // instance. |data| must have been deflated raw, i.e. with no headers. If the
  // uncompressed data exceeds |max_uncompressed_size|, returns empty.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void Inflate(base::span<const uint8_t> data,
               uint64_t max_uncompressed_size,
               GzipperCallback callback);

  // Compresses potentially unsafe |data| using this DataDecoder's service
  // instance.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void GzipCompress(base::span<const uint8_t> data, GzipperCallback callback);

  // Uncompresses potentially unsafe |data| using this DataDecoder's service
  // instance.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void GzipUncompress(base::span<const uint8_t> data, GzipperCallback callback);

  // Parses the potentially unsafe CBOR bytes in |cbor| using this
  // DataDecoder's service instance or some other platform-specific decoding
  // facility. The parser conforms to RFC 7049, except a few limitations:
  // - Does not support null or undefined values.
  // - Integers must fit in the 'int' type.
  // - The keys in Maps must be a string or byte-string.
  // - If at least one Map key is invalid, an error will be returned.
  //
  // Note that |callback| will only be called if the parsing operation succeeds
  // or fails before this DataDecoder is destroyed.
  void ParseCbor(base::span<const uint8_t> cbor, ValueParseCallback callback);

  // Validates the format of the potentially unsafe `pix_code`.
  void ValidatePixCode(const std::string& pix_code,
                       ValidationCallback callback);

 private:
  // The 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.
  base::TimeDelta idle_timeout_;

  // This instance's connection to the service. This connection is lazily
  // established and may be reset after long periods of idle time.
  mojo::Remote<mojom::DataDecoderService> service_;

  // Cancellation flag for any outstanding requests. When a request is
  // started, it takes a reference to this flag. Upon the destruction of this
  // instance, the flag is set to `true`. Any outstanding requests should check
  // this flag, and if it is `true`, they should not run the callback, per
  // the API guarantees above.
  scoped_refptr<CancellationFlag> cancel_requests_;
};

}  // namespace data_decoder

#endif  // SERVICES_DATA_DECODER_PUBLIC_CPP_DATA_DECODER_H_
