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

syntax = "proto2";

package components.feed.core.proto.libraries.api.internal;

option optimize_for = LITE_RUNTIME;

import "components/feed/core/proto/ui/stream/stream_structure.proto";
import "components/feed/core/proto/wire/action_payload.proto";
import "components/feed/core/proto/wire/consistency_token.proto";
import "components/feed/core/proto/wire/piet_shared_state_item.proto";

option java_package = "org.chromium.components.feed.core.proto.libraries.api.internal";
option java_outer_classname = "StreamDataProto";

// A StreamFeature represents a node within the tree forming the Stream.  The
// stream contains structure and content at multiple levels.  This
// structure is represented as a tree of features.  These features include
// Clusters, Hero Cards, Carousels, Piet Content, etc.  Nodes internal to the
// tree may have both content and children.
message StreamFeature {
  // The content id of this feature.
  optional string content_id = 1;

  // The parent feature if defined.  Most features will have a parent, the root
  // feature is the exception.
  optional string parent_id = 2;

  // Define the payloads for the various types of nodes present in the tree.
  oneof feature_payload {
    // Stream structure which defines how a stream will work and look.
    components.feed.core.proto.ui.stream.Stream stream = 4;

    // Card stream structure which defines how a card will work and look.
    components.feed.core.proto.ui.stream.Card card = 5;

    // Content stream structure.  Describes information which will be rendered
    // on screen.
    components.feed.core.proto.ui.stream.Content content = 6;

    // Cluster stream structure which defines a logical grouping of Content and
    // Cards.
    components.feed.core.proto.ui.stream.Cluster cluster = 7;

    // Legacy content
    StreamLegacyPayload legacy_content = 8;
  }
}

message StreamToken {
  // The content id of this feature.
  optional string content_id = 1;

  // The parent feature if defined.  Most features will have a parent, the root
  // feature is the exception.
  optional string parent_id = 2;

  // The Token
  optional bytes next_page_token = 3;
}

// Represents the UI state held in a mutation initiated by the UI.
message UiContext {
  extensions 1 to max;
}

// This represents a shared state item.
message StreamSharedState {
  optional string content_id = 1;
  oneof share_state {
    // A Piet shared state item.
    feedwire1.PietSharedStateItem piet_shared_state_item = 2;
  }
}

// This is the structure of the stream.  It is defined through the parent/child
// relationship and an operation.  This message will be journaled.  Reading
// the journal from start to end will fully define the structure of the stream.
message StreamStructure {
  // The defined set of DataOperations.
  enum Operation {
    UNKNOWN = 0;

    // All content in this Stream has been removed. See data_operation.proto.
    CLEAR_ALL = 1;

    // The item represented by content_id has been appended as a child to
    // parent_content_id. See data_operation.proto.
    UPDATE_OR_APPEND = 2;

    // The item represented by content_id has been removed. See
    // data_operation.proto.
    REMOVE = 3;

    // Indicates that the item represented by content_id is required by this
    // Stream and should not be deleted.
    REQUIRED_CONTENT = 4;
  }
  optional Operation operation = 1;

  // ContentId of the content that is appended, removed, or required.
  optional string content_id = 2;

  // ContentId of the parent of content_id that is being appended.
  optional string parent_content_id = 3;

  extensions 10000 to max;
}

// The internal version of a DataOperation.
message StreamDataOperation {
  // Defines the structure of the stream
  optional StreamStructure stream_structure = 1;

  // The payload (content) of the DataOperation.
  optional StreamPayload stream_payload = 2;
}

// This defines the content payload associated with a StreamDataOperation.
// Payload is what is stored in the Content portion of the persisted storage
// layer.  Each of the items defined here are persisted using the
// StreamContentId (String) as the key to the payload.  By default, the
// StreamContentId is formed by concatenation of the ContentId Table, followed
// by ContentDomain, then Id.  In addition, for content requiring prefix based
// queries, the Store will prefix the StreamContentId.
message StreamPayload {
  oneof payload {
    // This contains a feature within the tree.  These are stored based upon
    // the server defined StreamContentId (created by the ProtocolAdapter).
    StreamFeature stream_feature = 3;

    // This contains a shared state, such as the Piet shared state.  The
    // Feed store prepends a prefix (see
    // FeedStoreConstants.SHARED_STATE_PREFIX) so these can be retrieved
    // through a prefix query.
    StreamSharedState stream_shared_state = 4;

    // Continuation Token for a parent.  These are stored in the same way other
    // the stream_feature are stored.  They are treated the same as other
    // feature content when persisted.
    StreamToken stream_token = 5;

    // This is stored as a single content record.  It contains information about
    // each known session including $HEAD.  This is a list of the individual
    // sessions which are currently active.  This has a StreamContentId defined
    // by the SessionManager (see FeedSessionManager.STREAM_SESSION_CONTENT_ID).
    StreamSessions stream_sessions = 6;

    // The semantic data associated with a Feature.  These are stored as content
    // with a prefix added by the Store (see
    // FeedStoreConstants.SEMANTIC_PROPERTIES_PREFIX) allowing prefix queries.
    bytes semantic_data = 7;

    // The consistency token used to ensure that we are recording actions to
    // the same server store.
    feedwire1.ConsistencyToken consistency_token = 9;
  }
  reserved 8;
}

// Allow the payload to contain Legacy Stream content.
// TODO: Should this be removed, this was designed for legacy content
// which is currently not supported anywhere.
message StreamLegacyPayload {
  // String identifying the type of the legacy content.  This values is
  // opaque to the infrastructure.
  optional string type = 1;

  // The data making up the Legacy payload. This value is opaque to the
  // infrastructure.
  optional bytes data = 2;
}

// List of all the sessions.
message StreamSessions {
  // Represents the current sessions
  repeated StreamSession stream_session = 1;
}

// Persistence for a Session. This allows the UI to create a ModelProvider
// from an existing session.
message StreamSession {
  // Unique identifier for the session.
  optional string session_id = 1;

  // The milliseconds of either the time this session was created or the last
  // time content was added to the HEAD session.
  optional int64 legacy_time_millis = 2;

  // Metadata for the session. If this field is absent then fallback to
  // #legacy_time_millis.
  optional SessionMetadata session_metadata = 3;
}

// Metadata that describes a session.
message SessionMetadata {
  // The time in milliseconds that the most recent content was added to this
  // session.
  optional int64 last_added_time_millis = 1;

  // The time in milliseconds that this session was created.
  optional int64 creation_time_millis = 2;

  // The schema used to create this session.
  optional int32 schema_version = 3;
}

message StreamLocalAction {
  // See LocalActionMutation.ActionType
  optional int32 action = 1;

  optional string feature_content_id = 2;

  // When the action was recorded
  optional int64 timestamp_seconds = 3;
}

message StreamUploadableAction {
  optional string feature_content_id = 2;

  // The number of time this action was attempted to be recorded
  optional int32 upload_attempts = 3;

  // When the action was recorded
  optional int64 timestamp_seconds = 4;

  optional feedwire1.ActionPayload payload = 6;

  reserved 1, 5;  // deprecated fields
}

// An extension to the BasicLoggingMetadata which is used to hide the notion of
// the client needing this data in other places.
message ClientBasicLoggingMetadata {
  extend components.feed.core.proto.ui.stream.BasicLoggingMetadata {
    optional ClientBasicLoggingMetadata client_basic_logging_metadata =
        206218502;
  }

  // Time server filled out content.
  optional int64 availability_time_seconds = 1;
}
