// Copyright 2016 The Fuchsia Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";

package cobalt;

option go_package = "cobalt";

import "encrypted_message.proto";

///////////////////////////////////////////////////////////////
// Messages created in the Encoder and consumed in the Analyzer
///////////////////////////////////////////////////////////////

// A client-given value of a |MetricPart| to be encoded and collected by Cobalt.
// An Encoder encodes a |ValuePart| and produces an |ObservationPart|. An
// analyzer decodes an |ObservationPart| to recover the |ValuePart|. Cobalt
// supports different types of values but the type must match the type declared
// in the |MetricPart| definition.
message ValuePart {
  oneof data {
    // A human-readable, UTF8 string.
    string string_value = 1;

    // An integer.
    uint64 int_value = 2;

    // An uninterpreted sequence of bytes.
    bytes blob_value = 3;
  }
}

message ForculusObservation {
  // The encryption of a serialized ValuePart.
  bytes ciphertext = 1;

  bytes point_x = 2;
  bytes point_y = 3;
}

message RapporObservation {
  uint32 cohort = 1;

  bytes data = 2;
}

message BasicRapporObservation {
  bytes data = 1;
}

// Used with the No-op encoding. Note that this offers no client-side privacy-
// protection. Cobalt may still offer some privacy protection via the Shuffler
// and via differentially-private release.
message UnencodedObservation {
  // The raw-unencoded input value.
  ValuePart unencoded_value = 1;
}

// The encoding of a ValuePart. This is produced by an Encoder.
message ObservationPart {
  oneof value {
    UnencodedObservation unencoded = 1;
    ForculusObservation forculus = 2;
    RapporObservation rappor = 3;
    BasicRapporObservation basic_rappor = 4;
  }

  // The encoding_config_id, along with the customer_id and project_id
  // (specified in the containing Observation) form the primary key into the
  // "EncodingConfigs" table in the Cobalt configuration database. The value
  // column is an "EncodingConfig" proto message describing how this
  // ObservationPart is encoded.
  uint32 encoding_config_id = 5;  // e.g. 114=(Forculus with threshold=50)
}

// An Observation consists of one or more ObservationParts.
message Observation {
  // The keys are the names of the metric parts to which each ObservationPart
  // is associated.
  map<string, ObservationPart> parts = 1;
}

// ObservationMetadata describes the parts of an observation other than the
// secret payload.
message ObservationMetadata {
  // An Observation is for a particular metric.
  // The following three values together specify that metric.
  uint32 customer_id = 1;
  uint32 project_id = 2;
  uint32 metric_id = 3;  // e.g. 7 = City-And-Rating

  // The day on which the observation occurred, expressed as the zero-based
  // index relative to January 1, 1970.
  // i.e. 0 = January 1, 1970
  //      1 = January 2, 1970
  //      etc.
  //
  // We intentionally leave the meaning of this vague and leave it to each
  // Encoder Client to define how to make it precise. Which day it is depends on
  // time zone. The Encoder client is free to use the local time zone or a
  // different time zone. The Encoder client is free to add some random noise to
  // the time at which an event occurred and this might change the day.
  uint32 day_index = 4;
}

// A batch of encrypted Observations with common metadata. This is the unit
// sent from a Shuffler to an Analyzer. The Observations are encrypted to
// the public key of the Analyzer so the Shuffler cannot read them.
message ObservationBatch {
  // The common Metadata for all of the encrypted observations in this batch.
  //
  // This field is authenticated by virtue of being included in the
  // "associated data" part of the AEAD encryption of each
  // |encryped_observation|.
  ObservationMetadata meta_data = 1;

  // Each EncryptedMessage contains the ciphertext of an Observation that has
  // been encrypted to the public key of the Analyzer.
  repeated EncryptedMessage encrypted_observation = 2;
}

// An envelope contains multiple ObservationBatches. An encrypted Envelope
// is the unit sent from an Encoder client to a Shuffler.
message Envelope {
  repeated ObservationBatch batch = 1;
}
