// Copyright 2018 Google LLC
//
// 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 firestore.client;

option java_multiple_files = true;
option java_package = "com.google.firebase.firestore.proto";

option objc_class_prefix = "FSTPB";

import "google/firestore/v1/firestore.proto";
import "google/protobuf/timestamp.proto";

// A Target is a long-lived data structure representing a resumable listen on a
// particular user query. While the query describes what to listen to, the
// Target records data about when the results were last updated and enough
// information to be able to resume listening later.
message Target {
  // An auto-generated sequential numeric identifier for the target. This
  // serves as the identity of the target, and once assigned never changes.
  int32 target_id = 1;

  // The last snapshot version received from the Watch Service for this target.
  //
  // This is the same value as TargetChange.read_time
  // https://github.com/googleapis/googleapis/blob/master/google/firestore/v1/firestore.proto#L734
  google.protobuf.Timestamp snapshot_version = 2;

  // An opaque, server-assigned token that allows watching a query to be
  // resumed after disconnecting without retransmitting all the data that
  // matches the query. The resume token essentially identifies a point in
  // time from which the server should resume sending results.
  //
  // This is related to the snapshot_version in that the resume_token
  // effectively also encodes that value, but the resume_token is opaque and
  // sometimes encodes additional information.
  //
  // A consequence of this is that the resume_token should be used when asking
  // the server to reason about where this client is in the watch stream, but
  // the client should use the snapshot_version for its own purposes.
  //
  // This is the same value as TargetChange.resume_token
  // https://github.com/googleapis/googleapis/blob/master/google/firestore/v1/firestore.proto#L722
  bytes resume_token = 3;

  // A sequence number representing the last time this query was listened to,
  // used for garbage collection purposes.
  //
  // Conventionally this would be a timestamp value, but device-local clocks
  // are unreliable and they must be able to create new listens even while
  // disconnected. Instead this should be a monotonically increasing number
  // that's incremented on each listen call.
  //
  // This is different from the target_id since the target_id is an immutable
  // identifier assigned to the Target on first use while
  // last_listen_sequence_number is updated every time the query is listened
  // to.
  int64 last_listen_sequence_number = 4;

  // The server-side type of target to listen to.
  oneof target_type {
    // A target specified by a query.
    google.firestore.v1.Target.QueryTarget query = 5;

    // A target specified by a set of document names.
    google.firestore.v1.Target.DocumentsTarget documents = 6;
  }

  // Denotes the maximum snapshot version at which the associated query view
  // contained no limbo documents.
  google.protobuf.Timestamp last_limbo_free_snapshot_version = 7;
}

// Global state tracked across all Targets, tracked separately to avoid the
// need for extra indexes.
message TargetGlobal {
  // The highest numbered target id across all Targets.
  //
  // See Target.target_id.
  int32 highest_target_id = 1;

  // The highest numbered last_listen_sequence_number across all Targets.
  //
  // See Target.last_listen_sequence_number.
  int64 highest_listen_sequence_number = 2;

  // A global snapshot version representing the last consistent snapshot we
  // received from the backend. This is monotonically increasing and any
  // snapshots received from the backend prior to this version (e.g. for
  // targets resumed with a resume_token) should be suppressed (buffered) until
  // the backend has caught up to this snapshot_version again. This prevents
  // our cache from ever going backwards in time.
  //
  // This is updated whenever our we get a TargetChange with a read_time and
  // empty target_ids.
  google.protobuf.Timestamp last_remote_snapshot_version = 3;

  // On platforms that need it, holds the number of targets persisted.
  int32 target_count = 4;
}
