// Copyright 2022 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.

#pragma once

#include "pw_software_update/bundled_update.pwpb.h"
#include "pw_software_update/bundled_update.rpc.pwpb.h"
#include "pw_software_update/bundled_update_backend.h"
#include "pw_software_update/update_bundle_accessor.h"
#include "pw_status/status.h"
#include "pw_sync/borrow.h"
#include "pw_sync/lock_annotations.h"
#include "pw_sync/mutex.h"
#include "pw_work_queue/work_queue.h"

namespace pw::software_update {

// Implementation class for pw.software_update.BundledUpdate.
// See bundled_update.proto for RPC method documentation.
class BundledUpdateService
    : public pw_rpc::pwpb::BundledUpdate::Service<BundledUpdateService> {
 public:
  PW_MODIFY_DIAGNOSTICS_PUSH();
  PW_MODIFY_DIAGNOSTIC(ignored, "-Wmissing-field-initializers");
  BundledUpdateService(UpdateBundleAccessor& bundle,
                       BundledUpdateBackend& backend,
                       work_queue::WorkQueue& work_queue)
      : unsafe_status_{.state = BundledUpdateState::Enum::kInactive},
        status_(unsafe_status_, status_mutex_),
        backend_(backend),
        bundle_(bundle),
        bundle_open_(false),
        work_queue_(work_queue),
        work_enqueued_(false) {}
  PW_MODIFY_DIAGNOSTICS_POP();
  Status GetStatus(const pw::protobuf::Empty::Message& request,
                   BundledUpdateStatus::Message& response);

  // Sync
  Status Start(const StartRequest::Message& request,
               BundledUpdateStatus::Message& response);

  // Sync
  Status SetTransferred(const pw::protobuf::Empty::Message& request,
                        BundledUpdateStatus::Message& response);

  // Async
  Status Verify(const pw::protobuf::Empty::Message& request,
                BundledUpdateStatus::Message& response);

  // Async
  Status Apply(const pw::protobuf::Empty::Message& request,
               BundledUpdateStatus::Message& response);

  // Currently sync, should be async.
  // TODO: Make this async to support aborting verify/apply.
  Status Abort(const pw::protobuf::Empty::Message& request,
               BundledUpdateStatus::Message& response);

  // Sync
  Status Reset(const pw::protobuf::Empty::Message& request,
               BundledUpdateStatus::Message& response);

  // Notify the service that the bundle transfer has completed. The service has
  // no way to know when the bundle transfer completes, so users must invoke
  // this method in their transfer completion handler.
  //
  // After this call, the service will be in TRANSFERRED state if and only if
  // it was in the TRANSFERRING state.
  void NotifyTransferSucceeded();

  // TODO(davidrogers) Add a MaybeFinishApply() method that is called after
  // reboot to finish any need apply and verify work.

  // TODO:
  // VerifyProgress - to update % complete.
  // ApplyProgress - to update % complete.

 private:
  // Top-level lock for OTA state coherency. May be held for extended periods.
  sync::Mutex mutex_;
  // Nested lock for safe status updates and queries.
  sync::Mutex status_mutex_ PW_ACQUIRED_AFTER(mutex_);
  BundledUpdateStatus::Message unsafe_status_ PW_GUARDED_BY(status_mutex_);
  sync::Borrowable<BundledUpdateStatus::Message, sync::Mutex> status_;
  BundledUpdateBackend& backend_ PW_GUARDED_BY(mutex_);
  UpdateBundleAccessor& bundle_ PW_GUARDED_BY(mutex_);
  bool bundle_open_ PW_GUARDED_BY(mutex_);
  work_queue::WorkQueue& work_queue_ PW_GUARDED_BY(mutex_);
  bool work_enqueued_ PW_GUARDED_BY(mutex_);

  void DoVerify() PW_LOCKS_EXCLUDED(status_mutex_);
  void DoApply() PW_LOCKS_EXCLUDED(status_mutex_);
  void Finish(BundledUpdateResult::Enum result)
      PW_EXCLUSIVE_LOCKS_REQUIRED(mutex_) PW_LOCKS_EXCLUDED(status_mutex_);
  bool IsFinished() PW_EXCLUSIVE_LOCKS_REQUIRED(mutex_)
      PW_LOCKS_EXCLUDED(status_mutex_) {
    return status_.acquire()->state == BundledUpdateState::Enum::kFinished;
  }
};

}  // namespace pw::software_update
