// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COBALT_SRC_LOGGER_PRIVACY_ENCODER_H_
#define COBALT_SRC_LOGGER_PRIVACY_ENCODER_H_

#include "src/algorithms/privacy/count_min.h"
#include "src/algorithms/random/random.h"
#include "src/lib/statusor/statusor.h"
#include "src/pb/observation.pb.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/report_definition.pb.h"

namespace cobalt::logger {

// The PrivacyEncoder is used by the ObservationGenerator to add privacy to
// Observations (of any non-private observation type) generated by local
// aggregation procedures. The PrivateIndexObservations produced by the
// PrivacyEncoder are then written to the ObservationStore by the
// ObservationGenerator's ObservationWriter.
//
// |secure_gen| is used to perform the privacy encoding and therefore needs to be cryptographically
// secure.
// |gen| is used to perform non-deterministic encodings prior to the privacy encoding and therefore
// does not need to be cryptographically secure.
class PrivacyEncoder {
 public:
  explicit PrivacyEncoder(std::unique_ptr<SecureBitGeneratorInterface<uint32_t>> secure_gen,
                          std::unique_ptr<BitGeneratorInterface<uint32_t>> gen);

  // Returns a PrivacyEncoder with a private random number generator.
  static std::unique_ptr<PrivacyEncoder> MakeSecurePrivacyEncoder();

  virtual ~PrivacyEncoder() = default;

  // If the report definition does not specify a privacy level, MaybeMakeObservations returns
  // |observation|. Else, MaybeMakeObservations transforms a user contribution for a local
  // aggregation period into a list of private observations. If the local aggregation produced an
  // Observation for the period, then this should be passed as
  // |observation|. If not (i.e. if no events were logged during the
  // aggregation period), then |observation| should be nullptr.
  virtual lib::statusor::StatusOr<std::vector<std::unique_ptr<Observation>>>
  MaybeMakePrivateObservations(std::unique_ptr<Observation> observation,
                               const MetricDefinition &metric_def,
                               const ReportDefinition &report_def);

  // Returns the maximum index of a PrivateIndexObservation for the metric and report specified by
  // |metric_def| and |report_def|.
  static lib::statusor::StatusOr<uint64_t> MaxIndexForReport(const MetricDefinition &metric_def,
                                                             const ReportDefinition &report_def);

  // The number of sketch cells per hash function in CountMin sketch for a StringCounts report
  // |report_def|. Currently hard-coded to 10. Returns an error status if |report_def| is not of
  // type StringCounts.
  static lib::statusor::StatusOr<size_t> GetNumCountMinCellsPerHash(
      const ReportDefinition &report_def);

  // The number of hash functions in a CountMin sketch for a StringCounts report |report_def|.
  // Currently hard-coded to 5. Returns an error status if |report_def| is not of type StringCounts.
  static lib::statusor::StatusOr<size_t> GetNumCountMinHashes(const ReportDefinition &report_def);

 private:
  friend class PrivacyEncoderTest;

  lib::statusor::StatusOr<std::vector<std::unique_ptr<Observation>>> MakePrivateObservations(
      const Observation *observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def);

  lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVector(
      const Observation &observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def);

  static lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVectorForUniqueDeviceCount(
      const Observation &observation, const MetricDefinition &metric_def);

  lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVectorForPerDeviceIntegerReport(
      const Observation &observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def);

  lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVectorForFleetwideMeansReport(
      const Observation &observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def);

  static lib::statusor::StatusOr<std::vector<uint64_t>>
  PrepareIndexVectorForPerDeviceHistogramsReport(const Observation &observation,
                                                 const MetricDefinition &metric_def,
                                                 const ReportDefinition &report_def);

  lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVectorForFleetwideHistogramsReport(
      const Observation &observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def);

  lib::statusor::StatusOr<std::vector<uint64_t>> PrepareIndexVectorForStringCountsReport(
      const Observation &observation, const MetricDefinition &metric_def,
      const ReportDefinition &report_def, size_t num_cells_per_hash, size_t num_hashes);

  static std::vector<std::unique_ptr<Observation>> ObservationsFromIndices(
      const std::vector<uint64_t> &indices);

  lib::statusor::StatusOr<std::vector<uint64_t>> AddNoise(const std::vector<uint64_t> &indices,
                                                          const MetricDefinition &metric_def,
                                                          const ReportDefinition &report_def);

  static int64_t ClipValue(int64_t value, const ReportDefinition &report_def);

  static uint64_t ClipCount(uint64_t count, const ReportDefinition &report_def);

  std::unique_ptr<SecureBitGeneratorInterface<uint32_t>> secure_gen_;
  std::unique_ptr<BitGeneratorInterface<uint32_t>> gen_;
};

}  // namespace cobalt::logger

#endif  // COBALT_SRC_LOGGER_PRIVACY_ENCODER_H_
