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

#pragma once

#include <cstddef>

#include "pw_blob_store/blob_store.h"
#include "pw_protobuf/map_utils.h"
#include "pw_protobuf/message.h"
#include "pw_software_update/bundled_update_backend.h"
#include "pw_software_update/manifest_accessor.h"
#include "pw_stream/memory_stream.h"

namespace pw::software_update {

// UpdateBundleAccessor is responsible for parsing, verifying and providing
// target payload access of a software update bundle. It takes the following as
// inputs:
//
// 1. A software update bundle via `BlobStore`.
// 2. A `BundledUpdateBackend`, which implements project-specific update
//    operations such as enforcing project update policies and
//    verifying/applying target files on device.
//
// The verification is done according to TUF process. Payload can only be
// accessed after successful verification.
//
// Exmple of use:
//
// UpdateBundleAccessor bundle(blob,helper);
// auto status = bundle.OpenAndVerify(current_manifest);
// if (!status.ok()) {
//   // handle error
//   ...
// }
//
// // Examine and use payload.
// auto exist = bundle.IsTargetPayloadIncluded("audio");
// if (!exist.ok() || !exist.value()) {
//   // handle error
//   ...
// }
//
// auto payload_reader = bundle.GetTargetPayload("audio");
// // Process payload
// ...
//
// // Get bundle's manifest and write it to the given writer.
// status = bundle.WriteManifest(staged_manifest_writer);
// if (!status.ok()) {
//   // handle error
//   ...
// }
//
// status = bundle.Close();
// if (!status.ok()) {
//   // handle error
//   ...
// }
class UpdateBundleAccessor {
 public:
  // UpdateBundleAccessor
  // bundle - The software update bundle data on storage.
  // backend - Project-specific BundledUpdateBackend.
  // disable_verification - Disable verification.
  constexpr UpdateBundleAccessor(blob_store::BlobStore& bundle,
                                 BundledUpdateBackend& backend,
                                 bool disable_verification = false)
      : bundle_(bundle),
        backend_(backend),
        bundle_reader_(bundle_),
        disable_verification_(disable_verification) {}

  // Opens and verifies the software update bundle.
  //
  // Specifically, the opening process opens a blob reader to the given bundle
  // and initializes the bundle proto parser. No write will be allowed to the
  // bundle until Close() is called.
  //
  // If bundle verification is enabled (see the `option` argument in
  // the constructor), the verification process does the following:
  //
  // 1. Check whether the bundle contains an incoming new root metadata. If it
  // does, it verifies the root against the current on-device root. If
  // successful, the on-device root will be updated to the new root.
  //
  // 2. Verify the targets metadata against the current trusted root.
  //
  // 3. Either verify all target payloads (size and hash) or defer that
  // verification till when a target is accessed.
  //
  // 4. Invoke the backend to do downstream verification of the bundle.
  //
  // Returns:
  // OK - Bundle was successfully opened and verified.
  Status OpenAndVerify(const ManifestAccessor& current_manifest);

  // Closes the bundle by invalidating the verification and closing
  // the reader to release the read-only lock
  //
  // Returns:
  // OK - success.
  // DATA_LOSS - Error writing data or fail to verify written data.
  Status Close();

  // Writes the manifest of the staged bundle to the given writer.
  //
  // Returns:
  // FAILED_PRECONDITION - Bundle is not open and verified.
  // TODO(pwbug/456): Add other error codes if necessary.
  Status WriteManifest(stream::Writer& staged_manifest_writer);

  // Is the target payload present in the bundle (not personalized out).
  //
  // Returns:
  // OK - Whether or not the target_file was included in the UpdateBundle or
  //      whether it was personalized out.
  // FAILED_PRECONDITION - Bundle is not open and verified.
  // TODO(pwbug/456): Add other error codes if necessary.
  Result<bool> IsTargetPayloadIncluded(std::string_view target_file);

  // Returns a reader for the target file by `target_file` in the update
  // bundle.
  //
  // Returns:
  // A reader instance for the target file.
  // TODO(pwbug/456): Figure out a way to propagate error.
  stream::IntervalReader GetTargetPayload(std::string_view target_file);

  protobuf::Message GetDecoder() { return decoder_; }

 private:
  blob_store::BlobStore& bundle_;
  BundledUpdateBackend& backend_;
  blob_store::BlobStore::BlobReader bundle_reader_;
  protobuf::Message decoder_;
  bool disable_verification_;

  // Opens the bundle for read-only access and readies the parser.
  Status DoOpen();

  // Performs TUF and downstream custom verification.
  Status DoVerify();

  // The method checks whether the update bundle contains a root metadata
  // different from the on-device one. If it does, it performs the following
  // verification and upgrade flow:
  //
  // 1. Verify the signatures according to the on-device trusted
  // disable_verificationroot metadata
  //    obtained from the backend.
  // 2. Verify content of the new root metadata, including:
  //    1) Check role magic field.
  //    2) Check signature requirement. Specifically, check that no key is
  //       reused across different roles and keys are unique in the same
  //       requirement.
  //    3) Check key mapping. Specifically, check that all keys are unique,
  //       ECDSA keys, and the key ids are exactly the SHA256 of `key type +
  //       key scheme + key value`.
  // 3. Verify the signatures against the new root metadata.
  // 4. Check rollback.
  // 5. Update on-device root metadata.
  Status DoUpgradeRoot();
};

}  // namespace pw::software_update
