// 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 <cstdint>
#include <cstring>
#include <span>
#include <type_traits>
#include <utility>

#include "pw_bytes/span.h"
#include "pw_checksum/crc16_ccitt.h"
#include "pw_status/status.h"
#include "pw_stream/stream.h"

namespace pw::persistent_ram {

// A PersistentBufferWriter implements the pw::stream::Writer interface and
// provides handles to mutate and access the underlying data of a
// PersistentBuffer. This object should NOT be stored in persistent RAM.
//
// Only one writer should be open at a given time.
class PersistentBufferWriter : public stream::Writer {
 public:
  PersistentBufferWriter() = delete;

  size_t ConservativeWriteLimit() const override {
    return buffer_.size_bytes() - size_;
  }

 private:
  template <size_t>
  friend class PersistentBuffer;

  PersistentBufferWriter(ByteSpan buffer,
                         volatile size_t& size,
                         volatile uint16_t& checksum)
      : buffer_(buffer), size_(size), checksum_(checksum) {}

  // Implementation for writing data to this stream.
  Status DoWrite(ConstByteSpan data) override;

  ByteSpan buffer_;
  volatile size_t& size_;
  volatile uint16_t& checksum_;
};

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wuninitialized"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif

// When a PersistentBuffer is statically allocated in persistent memory, its
// state will persist across soft resets in accordance with the expected
// behavior of the underlying RAM. This object is completely safe to use before
// static constructors are called as its constructor is effectively a no-op.
//
// While the stored data can be read by PersistentBuffer's public functions,
// each public function must validate the integrity of the stored data. It's
// typically more performant to get a handle to a PersistentBufferWriter
// instead, as data is validated on creation of the PersistentBufferWriter,
// which allows access to the underlying data without needing to validate the
// data's integrity with each call to PersistentBufferWriter functions.
template <size_t kMaxSizeBytes>
class PersistentBuffer {
 public:
  // The default constructor intentionally does not initialize anything. This
  // allows a persistent buffer statically allocated in persistent RAM to be
  // highly available.
  //
  // Explicitly declaring an empty constructor rather than using the default
  // constructor prevents the object from being zero-initialized when the object
  // is value initialized. If this was left as a default constructor,
  // PersistentBuffer objects declared as value-initialized would be
  // zero-initialized.
  //
  //   // Value initialization:
  //   PersistentBuffer<256> persistent_buffer();
  //
  //   // Default initialization:
  //   PersistentBuffer<256> persistent_buffer;
  PersistentBuffer() {}
  // Disable copy and move constructors.
  PersistentBuffer(const PersistentBuffer&) = delete;
  PersistentBuffer(PersistentBuffer&&) = delete;
  // Explicit no-op destructor.
  ~PersistentBuffer() {}

  PersistentBufferWriter GetWriter() {
    if (!has_value()) {
      clear();
    }
    return PersistentBufferWriter(
        ByteSpan(const_cast<std::byte*>(buffer_), kMaxSizeBytes),
        size_,
        checksum_);
  }

  size_t size() const {
    if (has_value()) {
      return size_;
    }
    return 0;
  }

  const std::byte* data() const { return const_cast<std::byte*>(buffer_); }

  void clear() {
    size_ = 0;
    checksum_ = checksum::Crc16Ccitt::kInitialValue;
  }

  bool has_value() const {
    if (size_ > kMaxSizeBytes || size_ == 0) {
      return false;
    }

    // Check checksum. This is more costly.
    return checksum_ == checksum::Crc16Ccitt::Calculate(ConstByteSpan(
                            const_cast<std::byte*>(buffer_), size_));
  }

 private:
  // None of these members are initialized by the constructor by design.
  volatile uint16_t checksum_;
  volatile size_t size_;
  volatile std::byte buffer_[kMaxSizeBytes];
};

#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
}  // namespace pw::persistent_ram
