/*
 * 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
 *
 *      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 fcp.client;

import "google/protobuf/duration.proto";
import "fcp/client/engine/engine.proto";
import "tensorflow/core/framework/tensor.proto";

option java_package = "com.google.intelligence.fcp.client";
option java_multiple_files = true;

/**
 * This protocol buffer is used to report results and statistics of a Federated
 * Computation - including checking in with the server, running a plan, and
 * reporting back results - to the caller. It is a protocol buffer to support
 * sending it across language boundaries.
 */
message FLRunnerResult {
  reserved 1;
  // A RetryInfo returned to the caller for consideration in scheduling future
  // runs of this task.
  RetryInfo retry_info = 4;
  // An enum that summarizes whether the client has contributed to an FL/FA
  // round.
  enum ContributionResult {
    UNSPECIFIED = 0;
    SUCCESS = 1;
    // Any outcome that is not a success.
    FAIL = 2;
  }

  ContributionResult contribution_result = 5;
  reserved 2, 3;


  // All fields below are added by OnDevicePersonalization module for logging and
  // debugging purpose.
  // Debug message will be present if ContributionResult is FAIL.
  string error_message = 200;

  enum ErrorStatus {
    ERROR_STATUS_UNSPECIFIED = 0;
    // A TensorFlow error occurred.
    TENSORFLOW_ERROR = 1;
    // The input parameters are invalid.
    INVALID_ARGUMENT = 2;
    // An example iterator error occurred.
    EXAMPLE_ITERATOR_ERROR = 3;
    // Not eligible to execute task.
    NOT_ELIGIBLE = 4;
  }

  // Used to populate error happens in c++ to java code. Mainly for debug and
  // logging purpose.
  ErrorStatus error_status = 201;

  message ExampleStats {
    // For TensorlowSpec-based plans, this refers to the overall number of
    // elements returned by all ExampleIterator::Next() calls. For
    // ExampleQuerySpec-based plans, this refers to the total number of row counts
    // calculated at example store layer and passed via ExampleQueryResults.
    int32 example_count = 1;
    int64 example_size_bytes = 2;
  }

  // Used to record the stats of examples used in computation. Mainly used for
  // debug and logging purpose.
  ExampleStats example_stats = 202;
}

// A suggestion to the client when to retry the connection to the service next
// time
message RetryInfo {
  // Optional. If set, should be provided back to the next
  // RunFederatedComputation invocation.
  string retry_token = 1;

  // The suggested delay duration after which the client should
  // retry. Clients should ideally not retry any earlier than this.
  google.protobuf.Duration minimum_delay = 2;
}

/**
 * This protocol buffer is used to pass TensorflowSpec-based plan outputs across
 * the JNI boundary so they can be accessed in compatibility tests.
 */
message FLRunnerTensorflowSpecResult {
  // The outcome of running the plan.
  engine.PhaseOutcome outcome = 1;
  // The location of the output checkpoint file, if one was created.
  string checkpoint_output_filename = 2;
  // A map of output tensor names and values, if any.
  map<string, tensorflow.TensorProto> output_tensors = 3;
}
