// Copyright 2021 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 google.cloud.apigeeconnect.v1;

import "google/protobuf/duration.proto";
import "google/rpc/status.proto";
import "google/api/client.proto";

option csharp_namespace = "Google.Cloud.ApigeeConnect.V1";
option go_package = "google.golang.org/genproto/googleapis/cloud/apigeeconnect/v1;apigeeconnect";
option java_multiple_files = true;
option java_outer_classname = "TetherProto";
option java_package = "com.google.cloud.apigeeconnect.v1";
option php_namespace = "Google\\Cloud\\ApigeeConnect\\V1";
option ruby_package = "Google::Cloud::ApigeeConnect::V1";

// Tether provides a way for the control plane to send HTTP API requests to
// services in data planes that runs in a remote datacenter without
// requiring customers to open firewalls on their runtime plane.
service Tether {
  option (google.api.default_host) = "apigeeconnect.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";

  // Egress streams egress requests and responses. Logically, this is not
  // actually a streaming request, but uses streaming as a mechanism to flip
  // the client-server relationship of gRPC so that the server can act as a
  // client.
  // The listener, the RPC server, accepts connections from the dialer,
  // the RPC client.
  // The listener streams http requests and the dialer streams http responses.
  rpc Egress(stream EgressResponse) returns (stream EgressRequest) {
  }
}

// gRPC request payload for tether.
message EgressRequest {
  // Unique identifier for the request.
  string id = 1;

  // Actual payload to send to agent.
  Payload payload = 2;

  // Tether Endpoint.
  TetherEndpoint endpoint = 3;

  // GCP Project.
  // Format: `projects/{project_number}`.
  string project = 4;

  // Unique identifier for clients to trace their request/response.
  string trace_id = 5;

  // Timeout for the HTTP request.
  google.protobuf.Duration timeout = 6;
}

// Payload for EgressRequest.
message Payload {
  // The kind of payload.
  oneof kind {
    // The HttpRequest proto.
    HttpRequest http_request = 1;

    // The information of stream.
    StreamInfo stream_info = 2;

    // The action taken by agent.
    Action action = 3;
  }
}

// The Information of bi-directional stream.
message StreamInfo {
  // Unique identifier for the stream.
  string id = 1;
}

// The action taken by agent.
enum Action {
  // Unspecified Action.
  ACTION_UNSPECIFIED = 0;

  // Indicates that agent should open a new stream.
  OPEN_NEW_STREAM = 1;
}

// gRPC response payload for tether.
message EgressResponse {
  // Unique identifier for the response. Matches the EgressRequest's id.
  string id = 1;

  // HttpResponse.
  HttpResponse http_response = 2;

  // Errors from application when handling the http request.
  google.rpc.Status status = 3;

  // GCP Project.
  // Format: `projects/{project_number}`.
  string project = 4;

  // Unique identifier for clients to trace their request/response. Matches the
  // EgressRequest's trace id
  string trace_id = 5;

  // Tether Endpoint.
  TetherEndpoint endpoint = 6;

  // Name is the full resource path of endpoint.
  // Format: `projects/{project_number or project_id}/endpoints/{endpoint}`
  string name = 7;
}

// Endpoint indicates where the messages will be delivered.
enum TetherEndpoint {
  // Unspecified tether endpoint.
  TETHER_ENDPOINT_UNSPECIFIED = 0;

  // Apigee MART endpoint.
  APIGEE_MART = 1;

  // Apigee Runtime endpoint.
  APIGEE_RUNTIME = 2;

  // Apigee Mint Rating endpoint.
  APIGEE_MINT_RATING = 3;
}

// HTTP Scheme.
enum Scheme {
  // Unspecified scheme.
  SCHEME_UNSPECIFIED = 0;

  // HTTPS protocol.
  HTTPS = 1;
}

// The proto definition of http request.
message HttpRequest {
  // A unique identifier for the request.
  string id = 1;

  // The HTTP request method.
  // Valid methods: "GET", "HEAD", "POST", "PUT", "PATCH","DELETE".
  string method = 2;

  // The HTTP request URL.
  Url url = 3;

  // The HTTP request headers.
  repeated Header headers = 4;

  // HTTP request body.
  bytes body = 5;
}

// The proto definition of url.
// A url represents a URL and the general form represented is:
//
//  `[scheme://][google.cloud.apigeeconnect.v1.Url.host][path]`
message Url {
  // Scheme.
  Scheme scheme = 1;

  // Host or Host:Port.
  string host = 2;

  // Path starts with `/`.
  string path = 3;
}

// The http headers.
message Header {
  string key = 1;

  repeated string values = 2;
}

// The proto definition of http response.
message HttpResponse {
  // A unique identifier that matches the request ID.
  string id = 1;

  // Status of http response, e.g. "200 OK".
  string status = 2;

  // Status code of http response, e.g. 200.
  int32 status_code = 3;

  // The HTTP 1.1 response body.
  bytes body = 4;

  // The HTTP response headers.
  repeated Header headers = 5;

  // Content length records the length of the associated content. The
  // value -1 indicates that the length is unknown. Unless http method
  // is "HEAD", values >= 0 indicate that the given number of bytes may
  // be read from Body.
  int64 content_length = 6;
}
