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

#include "pw_blob_store/flat_file_system_entry.h"

#include <cstddef>
#include <mutex>
#include <span>

#include "pw_assert/check.h"
#include "pw_blob_store/blob_store.h"
#include "pw_file/flat_file_system.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"
#include "pw_sync/virtual_basic_lockable.h"

namespace pw::blob_store {

Status FlatFileSystemBlobStoreEntry::Init() {
  std::lock_guard lock(blob_store_lock_);
  if (initialized_) {
    return OkStatus();
  }
  const Status status = blob_store_.Init();
  initialized_ = status.ok();
  return status;
}

void FlatFileSystemBlobStoreEntry::EnsureInitialized() {
  {  // Only hold lock for initial check so Init() doesn't recursively lock.
    std::lock_guard lock(blob_store_lock_);
    if (initialized_) {
      return;
    }
  }

  // Don't inline the Init() into the DCHECK() as disabling the DCHECK()
  // statement would disable the Init() call as well.
  const Status status = Init();
  PW_DCHECK_OK(status);
}

StatusWithSize FlatFileSystemBlobStoreEntry::Name(std::span<char> dest) {
  EnsureInitialized();
  std::lock_guard lock(blob_store_lock_);
  BlobStore::BlobReader reader(blob_store_);
  if (const Status status = reader.Open(); !status.ok()) {
    // When a BlobStore is empty, Open() reports FAILED_PRECONDITION. The
    // FlatFileSystemService expects NOT_FOUND when a file is not present at the
    // entry.
    switch (status.code()) {
      case Status::FailedPrecondition().code():
        return StatusWithSize(Status::NotFound(), 0);
      case Status::Unavailable().code():
        return StatusWithSize(Status::Unavailable(), 0);
      default:
        return StatusWithSize(Status::Internal(), 0);
    }
  }
  return reader.GetFileName(dest);
}

size_t FlatFileSystemBlobStoreEntry::SizeBytes() {
  EnsureInitialized();
  std::lock_guard lock(blob_store_lock_);
  BlobStore::BlobReader reader(blob_store_);
  if (!reader.Open().ok()) {
    return 0;
  }
  return reader.ConservativeReadLimit();
}

// TODO(pwbug/488): This file can be deleted even though it is read-only.
// This type of behavior should be possible to express via the FileSystem RPC
// service.
Status FlatFileSystemBlobStoreEntry::Delete() {
  EnsureInitialized();
  std::lock_guard lock(blob_store_lock_);

  BlobStore::BlobWriterWithBuffer blob_writer(blob_store_);
  PW_TRY(blob_writer.Open());
  return blob_writer.Discard();
}

}  // namespace pw::blob_store
