// 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_assert/light.h"
#include "pw_checksum/crc16_ccitt.h"

namespace pw::persistent_ram {

// The Persistent class intentionally uses uninitialized memory, which triggers
// compiler warnings. Disable those warnings for this file.
PW_MODIFY_DIAGNOSTICS_PUSH();
PW_MODIFY_DIAGNOSTIC(ignored, "-Wuninitialized");
PW_MODIFY_DIAGNOSTIC_GCC(ignored, "-Wmaybe-uninitialized");

// A simple container for holding a value T with CRC16 integrity checking.
//
// A Persistent is simply a value T plus integrity checking for use in a
// persistent RAM section which is not initialized on boot.
//
// WARNING: Unlike a DoubleBufferedPersistent, a Persistent will be lost if a
// write/set operation is interrupted or otherwise not completed.
//
// TODO(pwbug/348): Consider a different integrity check implementation which
// does not use a 512B lookup table.
template <typename T>
class Persistent {
 public:
  // This object provides mutable access to the underlying object of a
  // Persistent<T>.
  //
  // WARNING: This object must remain in scope for any modifications of the
  // Underlying object. If the object is modified after the Mutator goes out
  // of scope, the CRC will not be updated to reflect changes, invalidating the
  // contents of the Persistent<T>!
  //
  // WARNING: Persistent<T>::has_value() will return false if there are
  // in-flight modifications by a Mutator that have not yet been flushed.
  class Mutator {
   public:
    explicit constexpr Mutator(Persistent<T>& persistent)
        : persistent_(persistent) {}
    ~Mutator() { persistent_.crc_ = persistent_.CalculateCrc(); }

    Mutator(const Mutator&) = delete;  // Copy constructor is disabled.

    T* operator->() { return const_cast<T*>(&persistent_.contents_); }

    // Be careful when sharing a reference or pointer to the underlying object.
    // Once the Mutator goes out of scope, any changes to the object will
    // invalidate the checksum. Avoid directly using the underlying object
    // unless you need to pass it to a function.
    T& value() { return persistent_.contents_; }
    T& operator*() { return *const_cast<T*>(&persistent_.contents_); }

   private:
    Persistent<T>& persistent_;
  };

  // Constructor which does nothing, meaning it never sets the value.
  constexpr Persistent() {}

  Persistent(const Persistent&) = delete;  // Copy constructor is disabled.
  Persistent(Persistent&&) = delete;       // Move constructor is disabled.
  ~Persistent() {}                         // The destructor does nothing.

  // Construct the value in-place.
  template <class... Args>
  const T& emplace(Args&&... args) {
    new (const_cast<T*>(&contents_)) T(std::forward<Args>(args)...);
    crc_ = CalculateCrc();
    return const_cast<T&>(contents_);
  }

  // Assignment operator.
  template <typename U = T>
  Persistent& operator=(U&& value) {
    contents_ = std::move(value);
    crc_ = CalculateCrc();
    return *this;
  }

  // Destroys any contained value.
  void reset() {
    // The trivial destructor is skipped as it's trivial.
    std::memset(const_cast<T*>(&contents_), 0, sizeof(contents_));
    crc_ = 0;
  }

  // Returns true if a value is held by the Persistent.
  bool has_value() const {
    return crc_ == CalculateCrc();  // There's a value if its CRC matches.
  }

  // Access the value.
  //
  // Precondition: has_value() must be true.
  const T& value() const {
    PW_ASSERT(has_value());
    return const_cast<T&>(contents_);
  }

  // Get a mutable handle to the underlying data.
  //
  // Precondition: has_value() must be true.
  Mutator mutator() {
    PW_ASSERT(has_value());
    return Mutator(*this);
  }

 private:
  friend class Mutator;

  static_assert(std::is_trivially_copy_constructible<T>::value,
                "If a Persistent persists across reboots, it is effectively "
                "loaded through a trivial copy constructor.");

  static_assert(std::is_trivially_destructible<T>::value,
                "A Persistent's destructor does not invoke the value's "
                "destructor, ergo only trivially destructible types are "
                "supported.");

  uint16_t CalculateCrc() const {
    return checksum::Crc16Ccitt::Calculate(
        std::as_bytes(std::span(const_cast<const T*>(&contents_), 1)));
  }

  // Use unions to denote that these members are never initialized by design and
  // on purpose. Volatile is used to ensure that the compiler cannot optimize
  // out operations where it seems like there is no further usage of a
  // Persistent as this may be on the next boot.
  union {
    volatile T contents_;
  };
  union {
    volatile uint16_t crc_;
  };
};

PW_MODIFY_DIAGNOSTICS_POP();

}  // namespace pw::persistent_ram
