// Copyright 2021 The Pigweed Authors
//
// 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";

package pw.software_update;

import "pw_protobuf_protos/common.proto";
import "pw_tokenizer/proto/options.proto";
import "google/protobuf/any.proto";

message BundledUpdateState {
  enum Enum {
    UNKNOWN = 0;  // Not an expected state in the OTA system; only for proto.

    // Valid methods in this state: Start()
    //
    // Transition:
    //   Start() succeeds --> TRANSFERRING
    //   Start() fails    --> FINISHED
    INACTIVE = 1;

    // Valid methods in this state: GetStatus(), Abort().
    //
    // Transitions:
    //   Transfer completes --> TRANSFERRED
    //   Transfer fails     --> FINISHED
    //   Abort() called     --> ABORTING
    TRANSFERRING = 2;

    // Valid methods in this state: GetStatus(), Abort(), Verify().
    //
    // Transitions:
    //   Verify() called    --> VERIFYING
    //   Apply() called     --> VERIFYING
    //   Abort() called     --> ABORTING
    TRANSFERRED = 3;

    // Valid methods in this state: GetStatus(), Abort().
    //
    // Transitions:
    //   Verifying finished --> VERIFIED
    //   Verifying failed   --> FINISHED
    //   Abort() called     --> ABORTING
    VERIFYING = 4;

    // Valid methods in this state: GetStatus(), Abort(), Apply().
    //
    // Transitions:
    //   Apply() called --> APPLYING
    //   Abort() called --> ABORTING
    VERIFIED = 5;

    // Valid methods in this state: GetStatus().
    //
    // Transitions:
    //   Apply() finished --> FINISHED; may require persisting across a reboot.
    //   Apply() failed   --> FINISHED; with error set.
    APPLYING = 6;

    // Valid methods in this state: GetStatus().
    //
    // Transitions:
    //   Abort finishes --> FINISHED
    //   Abort fails    --> FINISHED
    ABORTING = 7;

    // Valid methods in this state: GetStatus(), Reset().
    //
    // Terminal state indicating a finished update; whether successful or
    // not. Additional termination information available in completion_state
    // and possibly note.
    //
    // Transitions:
    //   Reset() succeeds --> INACTIVE
    //   Reset() fails    --> FINISHED
    FINISHED = 8;
  }
}

message BundledUpdateResult {
  enum Enum {
    UNKNOWN = 0;
    SUCCESS = 1;
    UNKNOWN_ERROR = 2;
    ABORTED = 3;
    TRANSFER_FAILED = 4;
    VERIFY_FAILED = 5;
    APPLY_FAILED = 6;
  }
}

message BundledUpdateStatus {
  BundledUpdateState.Enum state = 1;

  optional BundledUpdateResult.Enum result = 2;

  // This is the percentage of estimated progress for the current update
  // state in hundreths of a percent. (e.g. 5.00% = 500u)
  optional uint32 current_state_progress_hundreth_percent = 3;

  // If present, the active transfer ID for the update.
  optional uint32 transfer_id = 4;

  // The name of the update bundle. Not present when in INACTIVE state. This is
  // useful for enabling resuming of transfers across reboots or disconnects,
  // without transferring an expensive manifest.
  optional string bundle_filename = 5;

  // Additional information related to the state may be provided here.
  // Examples: "Failed verifying: ml_model.bin", "Flash partition couldn't be
  // acquired and was busy", etc. Can provide more granular information than
  // just the completion result.
  optional bytes note = 6 [(tokenizer.format) = TOKENIZATION_OPTIONAL];

  // Custom application data.
  optional google.protobuf.Any extended_status = 7;
}

message StartRequest {
  // If present, the filename for the staged file. This should persist across
  // reboots, and will be returned from GetStatus() until either the update
  // applies or is aborted.
  optional string bundle_filename = 1;
}

// TODO(b/235273688): Add documentation and details of the API contract.
service BundledUpdate {
  // TODO(keir): Offer GetCurrentManifest & GetStagedManifest() methods that
  // leverage pw_transfer to upload the manifest off the device, to enable host
  // logic.

  // Get current status of software update.
  rpc GetStatus(pw.protobuf.Empty) returns (BundledUpdateStatus);

  // Start a software update. Do any device-specific tasks needed to be ready
  // for update. Open pw_transfer channel used for staging bundle.
  // Returned status includes the transfer ID to use for bundle transfer.
  //
  // Precondition: Device update state must be INACTIVE.
  rpc Start(StartRequest) returns (BundledUpdateStatus);

  // Manually set the bundle status as transferred. It can be used to recover
  // a previously finished transfer or used when transfer happens on a side
  // channel without involvement of pw_transfer
  //
  // Precondition: Device update state must be INACTIVE or TRANSFERRING
  rpc SetTransferred(pw.protobuf.Empty) returns (BundledUpdateStatus);

  // Verify the bundle in the staging area. Returns immediately, but
  // verification runs asynchronously. Poll for completion with GetStatus().
  //
  // Precondition: Device update state must be TRANSFERRED.
  rpc Verify(pw.protobuf.Empty) returns (BundledUpdateStatus);

  // Apply the staged update. The update process will verify the staged bundle
  // or ensure that it was verified, apply the bundle, and in some cases reboot
  // the device. During this process, the device may be slow to respond.
  //
  // The RPC is async; callers must fetch status with GetStatus().
  //
  // Precondition: Device update state must be TRANSFERRED or VERIFIED.
  rpc Apply(pw.protobuf.Empty) returns (BundledUpdateStatus);

  // Abort any current software update in progress.
  // Precondition: Device update state must not be INACTIVE or FINISHED.
  rpc Abort(pw.protobuf.Empty) returns (BundledUpdateStatus);

  // Reset after a finished update. Device goes into INACTIVE state after.
  //
  // Precondition: Device update state must be FINISHED.
  rpc Reset(pw.protobuf.Empty) returns (BundledUpdateStatus);
}
