// 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/decoder.h"

#include <array>
#include <cstddef>

#include "pw_bytes/array.h"
#include "pw_fuzzer/fuzztest.h"
#include "pw_hdlc/internal/protocol.h"
#include "pw_unit_test/framework.h"

namespace pw::hdlc {
namespace {

using std::byte;
using namespace fuzzer;

TEST(Frame, Fields) {
  static constexpr auto kFrameData =
      bytes::String("\x05\xab\x42\x24\xf9\x54\xfb\x3d");
  auto result = Frame::Parse(kFrameData);
  ASSERT_TRUE(result.ok());
  Frame& frame = result.value();

  EXPECT_EQ(frame.address(), 2u);
  EXPECT_EQ(frame.control(), byte{0xab});

  EXPECT_EQ(frame.data().size(), 2u);
  EXPECT_EQ(frame.data()[0], byte{0x42});
  EXPECT_EQ(frame.data()[1], byte{0x24});
}

TEST(Frame, MultibyteAddress) {
  static constexpr auto kFrameData =
      bytes::String("\x2c\xd9\x33\x01\x02\xaf\xc8\x77\x48");
  auto result = Frame::Parse(kFrameData);
  ASSERT_TRUE(result.ok());
  Frame& frame = result.value();

  EXPECT_EQ(frame.address(), 0b11011000010110u);
  EXPECT_EQ(frame.control(), byte{0x33});

  EXPECT_EQ(frame.data().size(), 2u);
  EXPECT_EQ(frame.data()[0], byte{0x01});
  EXPECT_EQ(frame.data()[1], byte{0x02});
}

TEST(Frame, MultibyteAddressTooLong) {
  // 11-byte encoded address.
  constexpr auto kLongAddress =
      bytes::String("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01");
  static constexpr auto kFrameData = bytes::Concat(
      kLongAddress, bytes::String("\x33\x01\x02\xaf\xc8\x77\x48"));
  auto result = Frame::Parse(kFrameData);
  EXPECT_EQ(result.status(), Status::DataLoss());
}

TEST(Decoder, Clear) {
  DecoderBuffer<8> decoder;

  // Process a partial packet
  decoder.Process(bytes::String("~1234abcd"),
                  [](const Result<Frame>&) { FAIL(); });

  decoder.Clear();
  Status status = Status::Unknown();

  decoder.Process(
      bytes::String("~1234\xa3\xe0\xe3\x9b~"),
      [&status](const Result<Frame>& result) { status = result.status(); });

  EXPECT_EQ(OkStatus(), status);
}

TEST(Decoder, ExactFit) {
  DecoderBuffer<8> decoder;

  for (byte b : bytes::String("~1234\xa3\xe0\xe3\x9b")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }
  auto result = decoder.Process(kFlag);
  ASSERT_EQ(OkStatus(), result.status());
  ASSERT_EQ(result.value().data().size(), 2u);
  ASSERT_EQ(result.value().data()[0], byte{'3'});
  ASSERT_EQ(result.value().data()[1], byte{'4'});
}

TEST(Decoder, MinimumSizedBuffer) {
  DecoderBuffer<6> decoder;

  for (byte b : bytes::String("~12\xcd\x44\x53\x4f")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }

  auto result = decoder.Process(kFlag);
  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(result.value().data().size(), 0u);
}

TEST(Decoder, TooLargeForBuffer_ReportsResourceExhausted) {
  DecoderBuffer<8> decoder;

  for (byte b : bytes::String("~12345\x1c\x3a\xf5\xcb")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }
  EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());

  for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }
  EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
}

TEST(Decoder, TooLargeForBuffer_StaysWithinBufferBoundaries) {
  std::array<byte, 16> buffer = bytes::Initialized<16>('?');

  Decoder decoder(span(buffer.data(), 8));

  for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }

  for (size_t i = 8; i < buffer.size(); ++i) {
    ASSERT_EQ(byte{'?'}, buffer[i]);
  }

  EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());
}

TEST(Decoder, TooLargeForBuffer_DecodesNextFrame) {
  DecoderBuffer<8> decoder;

  for (byte b : bytes::String("~12345678901234567890\xf2\x19\x63\x90")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }
  EXPECT_EQ(Status::ResourceExhausted(), decoder.Process(kFlag).status());

  for (byte b : bytes::String("1234\xa3\xe0\xe3\x9b")) {
    EXPECT_EQ(Status::Unavailable(), decoder.Process(b).status());
  }
  EXPECT_EQ(OkStatus(), decoder.Process(kFlag).status());
}

void ProcessNeverCrashes(ConstByteSpan data) {
  DecoderBuffer<1024> decoder;
  for (byte b : data) {
    if (decoder.Process(b).status() != Status::Unavailable()) {
      decoder.Clear();
    }
  }
}

FUZZ_TEST(Decoder, ProcessNeverCrashes)
    .WithDomains(VectorOf<1024>(Arbitrary<byte>()));

}  // namespace
}  // namespace pw::hdlc
