/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package mesosproto;

import "mesos.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";


/**
 * Low-level scheduler event API.
 *
 * An event is described using the standard protocol buffer "union"
 * trick, see https://developers.google.com/protocol-buffers/docs/techniques#union.
 */
message Event {
  // Possible event types, followed by message definitions if
  // applicable.
  enum Type {
    REGISTERED = 1;
    REREGISTERED = 2;
    OFFERS = 3;
    RESCIND = 4;
    UPDATE = 5;
    MESSAGE = 6;
    FAILURE = 7;
    ERROR = 8;
  }

  message Registered {
    required FrameworkID framework_id = 1;
    required MasterInfo master_info = 2;
  }

  message Reregistered {
    required FrameworkID framework_id = 1;
    required MasterInfo master_info = 2;
  }

  message Offers {
    repeated Offer offers = 1;
  }

  message Rescind {
    required OfferID offer_id = 1;
  }

  message Update {
    required bytes uuid = 1; // TODO(benh): Replace with UpdateID.
    required TaskStatus status = 2;
  }

  message Message {
    required SlaveID slave_id = 1;
    required ExecutorID executor_id = 2;
    required bytes data = 3;
  }

  message Failure {
    optional SlaveID slave_id = 1;

    // If this was just a failure of an executor on a slave then
    // 'executor_id' will be set and possibly 'status' (if we were
    // able to determine the exit status).
    optional ExecutorID executor_id = 2;
    optional int32 status = 3;
  }

  message Error {
    required string message = 1;
  }

  // TODO(benh): Add a 'from' or 'sender'.

  // Type of the event, indicates which optional field below should be
  // present if that type has a nested message definition.
  required Type type = 1;

  optional Registered registered = 2;
  optional Reregistered reregistered = 3;
  optional Offers offers = 4;
  optional Rescind rescind = 5;
  optional Update update = 6;
  optional Message message = 7;
  optional Failure failure = 8;
  optional Error error = 9;
}


/**
 * Low-level scheduler call API.
 *
 * Like Event, a Call is described using the standard protocol buffer
 * "union" trick (see above).
 */
message Call {
  // Possible call types, followed by message definitions if
  // applicable.
  enum Type {
    REGISTER = 1;
    REREGISTER = 2;
    UNREGISTER = 3;
    REQUEST = 4;
    DECLINE = 5;
    REVIVE = 6;
    LAUNCH = 7;
    KILL = 8;
    ACKNOWLEDGE = 9;
    RECONCILE = 10;
    MESSAGE = 11;

    // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
    // already registered frameworks as a way of stopping offers from
    // being generated and other events from being sent by the master.
    // Note that this functionality existed originally to support
    // SchedulerDriver::abort which was only necessary to handle
    // exceptions getting thrown from within Scheduler callbacks,
    // something that is not an issue with the Event/Call API.
  }

  message Request {
    repeated mesosproto.Request requests = 1;
  }

  message Decline {
    repeated OfferID offer_ids = 1;
    optional Filters filters = 2;
  }

  message Launch {
    repeated TaskInfo task_infos = 1;
    repeated OfferID offer_ids = 2;
    optional Filters filters = 3;
  }

  message Kill {
    required TaskID task_id = 1;
  }

  message Acknowledge {
    required SlaveID slave_id = 1;
    required TaskID task_id = 2;
    required bytes uuid = 3;
  }

  // Allows the framework to query the status for non-terminal tasks.
  // This causes the master to send back the latest task status for
  // each task in 'statuses', if possible. Tasks that are no longer
  // known will result in a TASK_LOST update. If statuses is empty,
  // then the master will send the latest status for each task
  // currently known.
  // TODO(bmahler): Add a guiding document for reconciliation or
  // document reconciliation in-depth here.
  message Reconcile {
    repeated TaskStatus statuses = 1; // Should be non-terminal only.
  }

  message Message {
    required SlaveID slave_id = 1;
    required ExecutorID executor_id = 2;
    required bytes data = 3;
  }

  // Identifies who generated this call. Always necessary, but the
  // only thing that needs to be set for certain calls, e.g.,
  // REGISTER, REREGISTER, and UNREGISTER.
  required FrameworkInfo framework_info = 1;

  // Type of the call, indicates which optional field below should be
  // present if that type has a nested message definition.
  required Type type = 2;

  optional Request request = 3;
  optional Decline decline = 4;
  optional Launch launch = 5;
  optional Kill kill = 6;
  optional Acknowledge acknowledge = 7;
  optional Reconcile reconcile = 8;
  optional Message message = 9;
}
