// Copyright 2020 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 <algorithm>
#include <array>
#include <cstddef>
#include <cstring>
#include <functional>  // std::invoke

#include "pw_assert/light.h"
#include "pw_bytes/span.h"
#include "pw_checksum/crc32.h"
#include "pw_result/result.h"
#include "pw_status/status.h"

namespace pw::hdlc {

// Represents the contents of an HDLC frame -- the unescaped data between two
// flag bytes. Instances of Frame are only created when a full, valid frame has
// been read.
//
// For now, the Frame class assumes a single-byte control field and a 32-bit
// frame check sequence (FCS).
class Frame {
 private:
  static constexpr size_t kMinimumAddressSize = 1;
  static constexpr size_t kControlSize = 1;
  static constexpr size_t kFcsSize = sizeof(uint32_t);

 public:
  // The minimum size of a frame, excluding control bytes (flag or escape).
  static constexpr size_t kMinSizeBytes =
      kMinimumAddressSize + kControlSize + kFcsSize;

  static Result<Frame> Parse(ConstByteSpan frame);

  constexpr uint64_t address() const { return address_; }

  constexpr std::byte control() const { return control_; }

  constexpr ConstByteSpan data() const { return data_; }

 private:
  // Creates a Frame with the specified data. The data MUST be valid frame data
  // with a verified frame check sequence.
  constexpr Frame(uint64_t address, std::byte control, ConstByteSpan data)
      : data_(data), address_(address), control_(control) {}

  ConstByteSpan data_;
  uint64_t address_;
  std::byte control_;
};

// The Decoder class facilitates decoding of data frames using the HDLC
// protocol, by returning packets as they are decoded and storing incomplete
// data frames in a buffer.
//
// The Decoder class does not own the buffer it writes to. It can be used to
// write bytes to any buffer. The DecoderBuffer template class, defined below,
// allocates a buffer.
class Decoder {
 public:
  constexpr Decoder(ByteSpan buffer)
      : buffer_(buffer),
        last_read_bytes_({}),
        last_read_bytes_index_(0),
        current_frame_size_(0),
        state_(State::kInterFrame) {}

  Decoder(const Decoder&) = delete;
  Decoder& operator=(const Decoder&) = delete;

  // Parses a single byte of an HDLC stream. Returns a Result with the complete
  // frame if the byte completes a frame. The status is the following:
  //
  //     OK - A frame was successfully decoded. The Result contains the Frame,
  //         which is invalidated by the next Process call.
  //     UNAVAILABLE - No frame is available.
  //     RESOURCE_EXHAUSTED - A frame completed, but it was too large to fit in
  //         the decoder's buffer.
  //     DATA_LOSS - A frame completed, but it was invalid. The frame was
  //         incomplete or the frame check sequence verification failed.
  //
  Result<Frame> Process(std::byte b);

  // Processes a span of data and calls the provided callback with each frame or
  // error.
  template <typename F, typename... Args>
  void Process(ConstByteSpan data, F&& callback, Args&&... args) {
    for (std::byte b : data) {
      auto result = Process(b);
      if (result.status() != Status::Unavailable()) {
        std::invoke(
            std::forward<F>(callback), std::forward<Args>(args)..., result);
      }
    }
  }

  // Returns the maximum size of the Decoder's frame buffer.
  size_t max_size() const { return buffer_.size(); }

  // Clears and resets the decoder.
  void Clear() {
    state_ = State::kInterFrame;
    Reset();
  };

 private:
  // State enum class is used to make the Decoder a finite state machine.
  enum class State {
    kInterFrame,
    kFrame,
    kFrameEscape,
  };

  void Reset() {
    current_frame_size_ = 0;
    last_read_bytes_index_ = 0;
    fcs_.clear();
  }

  void AppendByte(std::byte new_byte);

  Status CheckFrame() const;

  bool VerifyFrameCheckSequence() const;

  const ByteSpan buffer_;

  // Ring buffer of the last four bytes read into the current frame, to allow
  // calculating the frame's CRC incrementally. As data is evicted from this
  // buffer, it is added to the running CRC. Once a frame is complete, the
  // buffer contains the frame's FCS.
  std::array<std::byte, sizeof(uint32_t)> last_read_bytes_;
  size_t last_read_bytes_index_;

  // Incremental checksum of the current frame.
  checksum::Crc32 fcs_;

  size_t current_frame_size_;

  State state_;
};

// DecoderBuffers declare a buffer along with a Decoder.
template <size_t kSizeBytes>
class DecoderBuffer : public Decoder {
 public:
  DecoderBuffer() : Decoder(frame_buffer_) {}

  // Returns the maximum length of the bytes that can be inserted in the bytes
  // buffer.
  static constexpr size_t max_size() { return kSizeBytes; }

 private:
  static_assert(kSizeBytes >= Frame::kMinSizeBytes);

  std::array<std::byte, kSizeBytes> frame_buffer_;
};

}  // namespace pw::hdlc
