// 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: 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);
}
