// Copyright 2020 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
//
//   https://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";

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

package google.showcase.v1beta1;

option go_package = "github.com/googleapis/gapic-showcase/server/genproto";
option java_package = "com.google.showcase.v1beta1";
option java_multiple_files = true;
option ruby_package = "Google::Showcase::V1beta1";

service SequenceService {
  // This service is meant to only run locally on the port 7469 (keypad digits
  // for "show").
  option (google.api.default_host) = "localhost:7469";

  // Creates a sequence.
  rpc CreateSequence(CreateSequenceRequest) returns (Sequence) {
    option (google.api.http) = {
      post: "/v1beta1/sequences"
      body: "sequence"
    };
    option (google.api.method_signature) = "sequence";
  };

    // Creates a sequence.
  rpc CreateStreamingSequence(CreateStreamingSequenceRequest) returns (StreamingSequence) {
    option (google.api.http) = {
      post: "/v1beta1/streamingSequences"
      body: "streaming_sequence"
    };
    option (google.api.method_signature) = "streaming_sequence";
  };

  // Retrieves a sequence.
  rpc GetSequenceReport(GetSequenceReportRequest) returns (SequenceReport) {
    option (google.api.http) = {
      get: "/v1beta1/{name=sequences/*/sequenceReport}"
    };
    option (google.api.method_signature) = "name";
  };

  // Retrieves a sequence.
  rpc GetStreamingSequenceReport(GetStreamingSequenceReportRequest) returns (StreamingSequenceReport) {
    option (google.api.http) = {
      get: "/v1beta1/{name=streamingSequences/*/streamingSequenceReport}"
    };
    option (google.api.method_signature) = "name";
  };

  // Attempts a sequence.
  rpc AttemptSequence(AttemptSequenceRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1beta1/{name=sequences/*}"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  };

  // Attempts a streaming sequence.
  // May not function as expected in HTTP mode due to when http statuses are sent
  // See https://github.com/googleapis/gapic-showcase/issues/1377 for more details
  rpc AttemptStreamingSequence(AttemptStreamingSequenceRequest) returns  (stream AttemptStreamingSequenceResponse) {
    option (google.api.http) = {
    post: "/v1beta1/{name=streamingSequences/*}:stream"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  };
}

message Sequence {
  option (google.api.resource) = {
    type: "showcase.googleapis.com/Sequence"
    pattern: "sequences/{sequence}"
  };

  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A server response to an RPC Attempt in a sequence.
  message Response {
    // The status to return for an individual attempt.
    google.rpc.Status status = 1;

    // The amount of time to delay sending the response.
    google.protobuf.Duration delay = 2;
  }

  // Sequence of responses to return in order for each attempt. If empty, the
  // default response is an immediate OK.
  repeated Response responses = 2;
}

message StreamingSequence {
  option (google.api.resource) = {
    type: "showcase.googleapis.com/StreamingSequence"
    pattern: "streamingSequences/{streaming_sequence}"
  };

  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The Content that the stream will send
  string content = 2;

  // A server response to an RPC Attempt in a sequence.
  message Response {
    // The status to return for an individual attempt.
    google.rpc.Status status = 1;

    // The amount of time to delay sending the response.
    google.protobuf.Duration delay = 2;

    // The index that the status should be sent
    int32 response_index = 3;
  }

  // Sequence of responses to return in order for each attempt. If empty, the
  // default response is an immediate OK.
  repeated Response responses = 3;
}


message StreamingSequenceReport {
  option (google.api.resource) = {
    type: "showcase.googleapis.com/StreamingSequenceReport"
    pattern: "streamingSequences/{streaming_sequence}/streamingSequenceReport"
  };

  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Contains metrics on individual RPC Attempts in a sequence.
  message Attempt {
    // The attempt number - starting at 0.
    int32 attempt_number = 1;

    // The deadline dictated by the attempt to the server.
    google.protobuf.Timestamp attempt_deadline = 2;

    // The time that the server responded to the RPC attempt. Used for
    // calculating attempt_delay.
    google.protobuf.Timestamp response_time = 3;

    // The server perceived delay between sending the last response and
    // receiving this attempt. Used for validating attempt delay backoff.
    google.protobuf.Duration attempt_delay = 4;

    // The status returned to the attempt.
    google.rpc.Status status = 5;

  }

  // The set of RPC attempts received by the server for a Sequence.
  repeated Attempt attempts = 2;
}

message SequenceReport {
  option (google.api.resource) = {
    type: "showcase.googleapis.com/SequenceReport"
    pattern: "sequences/{sequence}/sequenceReport"
  };

  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Contains metrics on individual RPC Attempts in a sequence.
  message Attempt {
    // The attempt number - starting at 0.
    int32 attempt_number = 1;

    // The deadline dictated by the attempt to the server.
    google.protobuf.Timestamp attempt_deadline = 2;

    // The time that the server responded to the RPC attempt. Used for
    // calculating attempt_delay.
    google.protobuf.Timestamp response_time = 3;

    // The server perceived delay between sending the last response and
    // receiving this attempt. Used for validating attempt delay backoff.
    google.protobuf.Duration attempt_delay = 4;

    // The status returned to the attempt.
    google.rpc.Status status = 5;
  }

  // The set of RPC attempts received by the server for a Sequence.
  repeated Attempt attempts = 2;
}

message CreateSequenceRequest {
  Sequence sequence = 1;
}

message CreateStreamingSequenceRequest {
  StreamingSequence streaming_sequence = 1;
}

message AttemptSequenceRequest {
  string name = 1 [
    (google.api.resource_reference).type = "showcase.googleapis.com/Sequence",
    (google.api.field_behavior) = REQUIRED
  ];

}

message AttemptStreamingSequenceRequest {
  string name = 1 [
    (google.api.resource_reference).type = "showcase.googleapis.com/StreamingSequence",
    (google.api.field_behavior) = REQUIRED
  ];
  
  // used to send the index of the last failed message
  // in the string "content" of an AttemptStreamingSequenceResponse
  // needed for stream resumption logic testing
  int32 last_fail_index = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// The response message for the Echo methods.
message AttemptStreamingSequenceResponse {
  // The content specified in the request.
  string content = 1;

}

message GetSequenceReportRequest {
  string name = 1 [
    (google.api.resource_reference).type =
        "showcase.googleapis.com/SequenceReport",
    (google.api.field_behavior) = REQUIRED
  ];
}

message GetStreamingSequenceReportRequest {
  string name = 1 [
    (google.api.resource_reference).type =
        "showcase.googleapis.com/StreamingSequenceReport",
    (google.api.field_behavior) = REQUIRED
  ];
}
