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