// Copyright 2017 Google Inc.
//
// 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.devtools.clouddebugger.v2;

import "google/api/annotations.proto";
import "google/devtools/clouddebugger/v2/data.proto";
import "google/protobuf/empty.proto";

option go_package = "google.golang.org/genproto/googleapis/devtools/clouddebugger/v2;clouddebugger";
option java_multiple_files = true;
option java_outer_classname = "ControllerProto";
option java_package = "com.google.devtools.clouddebugger.v2";


// The Controller service provides the API for orchestrating a collection of
// debugger agents to perform debugging tasks. These agents are each attached
// to a process of an application which may include one or more replicas.
//
// The debugger agents register with the Controller to identify the application
// being debugged, the Debuggee. All agents that register with the same data,
// represent the same Debuggee, and are assigned the same `debuggee_id`.
//
// The debugger agents call the Controller to retrieve  the list of active
// Breakpoints. Agents with the same `debuggee_id` get the same breakpoints
// list. An agent that can fulfill the breakpoint request updates the
// Controller with the breakpoint result. The controller selects the first
// result received and discards the rest of the results.
// Agents that poll again for active breakpoints will no longer have
// the completed breakpoint in the list and should remove that breakpoint from
// their attached process.
//
// The Controller service does not provide a way to retrieve the results of
// a completed breakpoint. This functionality is available using the Debugger
// service.
service Controller2 {
  // Registers the debuggee with the controller service.
  //
  // All agents attached to the same application should call this method with
  // the same request content to get back the same stable `debuggee_id`. Agents
  // should call this method again whenever `google.rpc.Code.NOT_FOUND` is
  // returned from any controller method.
  //
  // This allows the controller service to disable the agent or recover from any
  // data loss. If the debuggee is disabled by the server, the response will
  // have `is_disabled` set to `true`.
  rpc RegisterDebuggee(RegisterDebuggeeRequest) returns (RegisterDebuggeeResponse) {
    option (google.api.http) = { post: "/v2/controller/debuggees/register" body: "*" };
  }

  // Returns the list of all active breakpoints for the debuggee.
  //
  // The breakpoint specification (location, condition, and expression
  // fields) is semantically immutable, although the field values may
  // change. For example, an agent may update the location line number
  // to reflect the actual line where the breakpoint was set, but this
  // doesn't change the breakpoint semantics.
  //
  // This means that an agent does not need to check if a breakpoint has changed
  // when it encounters the same breakpoint on a successive call.
  // Moreover, an agent should remember the breakpoints that are completed
  // until the controller removes them from the active list to avoid
  // setting those breakpoints again.
  rpc ListActiveBreakpoints(ListActiveBreakpointsRequest) returns (ListActiveBreakpointsResponse) {
    option (google.api.http) = { get: "/v2/controller/debuggees/{debuggee_id}/breakpoints" };
  }

  // Updates the breakpoint state or mutable fields.
  // The entire Breakpoint message must be sent back to the controller
  // service.
  //
  // Updates to active breakpoint fields are only allowed if the new value
  // does not change the breakpoint specification. Updates to the `location`,
  // `condition` and `expression` fields should not alter the breakpoint
  // semantics. These may only make changes such as canonicalizing a value
  // or snapping the location to the correct line of code.
  rpc UpdateActiveBreakpoint(UpdateActiveBreakpointRequest) returns (UpdateActiveBreakpointResponse) {
    option (google.api.http) = { put: "/v2/controller/debuggees/{debuggee_id}/breakpoints/{breakpoint.id}" body: "*" };
  }
}

// Request to register a debuggee.
message RegisterDebuggeeRequest {
  // Debuggee information to register.
  // The fields `project`, `uniquifier`, `description` and `agent_version`
  // of the debuggee must be set.
  Debuggee debuggee = 1;
}

// Response for registering a debuggee.
message RegisterDebuggeeResponse {
  // Debuggee resource.
  // The field `id` is guranteed to be set (in addition to the echoed fields).
  Debuggee debuggee = 1;
}

// Request to list active breakpoints.
message ListActiveBreakpointsRequest {
  // Identifies the debuggee.
  string debuggee_id = 1;

  // A wait token that, if specified, blocks the method call until the list
  // of active breakpoints has changed, or a server selected timeout has
  // expired.  The value should be set from the last returned response.
  string wait_token = 2;

  // If set to `true`, returns `google.rpc.Code.OK` status and sets the
  // `wait_expired` response field to `true` when the server-selected timeout
  // has expired (recommended).
  //
  // If set to `false`, returns `google.rpc.Code.ABORTED` status when the
  // server-selected timeout has expired (deprecated).
  bool success_on_timeout = 3;
}

// Response for listing active breakpoints.
message ListActiveBreakpointsResponse {
  // List of all active breakpoints.
  // The fields `id` and `location` are guaranteed to be set on each breakpoint.
  repeated Breakpoint breakpoints = 1;

  // A wait token that can be used in the next method call to block until
  // the list of breakpoints changes.
  string next_wait_token = 2;

  // The `wait_expired` field is set to true by the server when the
  // request times out and the field `success_on_timeout` is set to true.
  bool wait_expired = 3;
}

// Request to update an active breakpoint.
message UpdateActiveBreakpointRequest {
  // Identifies the debuggee being debugged.
  string debuggee_id = 1;

  // Updated breakpoint information.
  // The field 'id' must be set.
  Breakpoint breakpoint = 2;
}

// Response for updating an active breakpoint.
// The message is defined to allow future extensions.
message UpdateActiveBreakpointResponse {

}
