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

#include "pw_hdlc_lite/decoder.h"

#include "pw_checksum/ccitt_crc16.h"
#include "pw_log/log.h"

using std::byte;

namespace pw::hdlc_lite {
namespace {

constexpr byte kHdlcFrameDelimiter = byte{0x7E};
constexpr byte kHdlcEscape = byte{0x7D};
constexpr byte kHdlcUnescapingConstant = byte{0x20};

}  // namespace

Result<ConstByteSpan> Decoder::AddByte(const byte new_byte) {
  switch (state_) {
    case DecoderState::kPacketActive: {
      if (new_byte != kHdlcFrameDelimiter) {
        // Packet active case
        if (new_byte != kHdlcEscape) {
          return Result<ConstByteSpan>(AddEscapedByte(new_byte));
        }
        state_ = DecoderState::kEscapeNextByte;
        return Result<ConstByteSpan>(Status::UNAVAILABLE);
      }
      // Packet complete case
      state_ = DecoderState::kNoPacket;
      Status status = PacketStatus();
      if (status.ok()) {
        // Common case: Happy Packet
        // Returning size_ - 2 is to trim off the 2-byte CRC value.
        return Result<ConstByteSpan>(frame_buffer_.first(size_ - 2));
      }
      if (status == Status::DATA_LOSS && size_ == 0) {
        // Uncommon case: Dropped an ending frame delimiter byte somewhere.
        // This happens if a delimiter byte was lost or corrupted which causes
        // the decoder to fall out of sync with the incoming flow of packets.
        // Recovery is done by switching to active mode assuming that the frame
        // delimiter "close" byte we just saw is actually a start delimiter.
        PW_LOG_ERROR(
            "Detected empty packet. Assuming out of sync; trying recovery");
        clear();
        state_ = DecoderState::kPacketActive;
        return Result<ConstByteSpan>(Status::UNAVAILABLE);
      }
      // Otherwise, forward the status from PacketStatus().
      return Result<ConstByteSpan>(status);
    }

    case DecoderState::kEscapeNextByte: {
      byte escaped_byte = new_byte ^ kHdlcUnescapingConstant;
      if (escaped_byte != kHdlcEscape && escaped_byte != kHdlcFrameDelimiter) {
        PW_LOG_WARN(
            "Suspicious escaped byte: 0x%02x; should only need to escape frame "
            "delimiter and escape byte",
            static_cast<int>(escaped_byte));
      }
      state_ = DecoderState::kPacketActive;
      return Result<ConstByteSpan>(AddEscapedByte(escaped_byte));
    }

    case DecoderState::kNoPacket: {
      if (new_byte != kHdlcFrameDelimiter) {
        PW_LOG_ERROR("Unexpected starting byte to the frame: 0x%02x",
                     static_cast<int>(new_byte));
        return Result<ConstByteSpan>(Status::UNAVAILABLE);
      }
      clear();
      state_ = DecoderState::kPacketActive;
      return Result<ConstByteSpan>(Status::UNAVAILABLE);
    }
  }
  return Result<ConstByteSpan>(Status::UNAVAILABLE);
}

bool Decoder::CheckCrc() const {
  uint16_t expected_crc =
      checksum::CcittCrc16(frame_buffer_.first(size_ - 2), 0xFFFF);
  uint16_t actual_crc;
  std::memcpy(&actual_crc, (frame_buffer_.data() + size_ - 2), 2);
  return actual_crc == expected_crc;
}

Status Decoder::AddEscapedByte(const byte new_byte) {
  if (size_ >= max_size()) {
    // Increasing the size to flag the overflow case when the packet is complete
    size_++;
    return Status::RESOURCE_EXHAUSTED;
  }
  frame_buffer_[size_++] = new_byte;
  return Status::UNAVAILABLE;
}

Status Decoder::PacketStatus() const {
  if (size_ < 2) {
    PW_LOG_ERROR(
        "Received %d-byte packet; packets must at least have 2 CRC bytes",
        static_cast<int>(size_));
    return Status::DATA_LOSS;
  }

  if (size_ > max_size()) {
    PW_LOG_ERROR("Packet size [%zu] exceeds the maximum buffer size [%zu]",
                 size_,
                 max_size());
    return Status::RESOURCE_EXHAUSTED;
  }

  if (!CheckCrc()) {
    PW_LOG_ERROR("CRC verification failed for packet");
    return Status::DATA_LOSS;
  }

  return Status::OK;
}

}  // namespace pw::hdlc_lite
