// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2025 The Eigen Authors
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template <typename Scalar, typename Packet>
void verify_data(const Scalar* data_in, const Scalar* data_out, const Packet& a, Index begin, Index count) {
  constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
  bool ok = true;
  for (Index i = begin; i < begin + count; i++) {
    ok = ok && numext::equal_strict(data_in[i], data_out[i]);
  }
  if (!ok) {
    std::cout << "begin: " << begin << ", count: " << count << "\n";
    std::cout << "Scalar type: " << type_name(Scalar()) << " x " << PacketSize << "\n";
    std::cout << "data in:  {";
    for (Index i = 0; i < PacketSize; i++) {
      if (i > 0) std::cout << ",";
      if (i < begin || i >= begin + count) {
        std::cout << "MASK";
      } else {
        std::cout << data_in[i];
      }
    }
    std::cout << "}\n";
    std::cout << "data out: {";
    for (Index i = 0; i < PacketSize; i++) {
      if (i > 0) std::cout << ",";
      if (i < begin || i >= begin + count) {
        std::cout << "MASK";
      } else {
        std::cout << data_out[i];
      }
    }
    std::cout << "}\n";
    std::cout << "packet:   ";
    std::cout << internal::postream(a) << "\n";
  }
  VERIFY(ok);
}

template <typename Scalar, int PacketSize, bool Run = internal::find_packet_by_size<Scalar, PacketSize>::value>
struct packet_segment_test_impl {
  using Packet = typename internal::find_packet_by_size<Scalar, PacketSize>::type;
  static void test_unaligned() {
    // test loading a packet segment from unaligned memory that includes unallocated memory

    // | X   X   X   X | *   *   *   X | X   X   X   X |
    //    begin -> { X | *   *   *   } <- begin + count

    VectorX<Scalar> data_in(PacketSize), data_out(PacketSize);
    data_in.setRandom();
    data_out.setRandom();

    Scalar* unaligned_data_in = data_in.data() - 1;
    Scalar* unaligned_data_out = data_out.data() - 1;

    Index begin = 1;
    Index count = PacketSize - 1;

    Packet a = internal::ploaduSegment<Packet>(unaligned_data_in, begin, count);
    internal::pstoreuSegment<Scalar, Packet>(unaligned_data_out, a, begin, count);

    verify_data(unaligned_data_in, unaligned_data_out, a, begin, count);

    // test loading the entire packet

    data_in.setRandom();
    data_out.setRandom();

    unaligned_data_in = data_in.data();
    unaligned_data_out = data_out.data();

    begin = 0;
    count = PacketSize;

    Packet b = internal::ploaduSegment<Packet>(unaligned_data_in, begin, count);
    internal::pstoreuSegment<Scalar, Packet>(unaligned_data_out, b, begin, count);

    verify_data(unaligned_data_in, unaligned_data_out, b, begin, count);

    // test loading an empty packet segment in unallocated memory
    count = 0;

    for (begin = 0; begin < PacketSize; begin++) {
      data_in.setRandom();
      data_out = data_in;
      Packet c = internal::ploaduSegment<Packet>(data_in.data(), begin, count);
      internal::pstoreuSegment<Scalar, Packet>(data_out.data(), c, begin, count);
      // verify that ploaduSegment / pstoreuSegment did nothing
      VERIFY_IS_CWISE_EQUAL(data_in, data_out);
    }
  }
  static void test_aligned() {
    // test loading a packet segment from aligned memory that includes unallocated memory

    // | X   X   X   X | *   *   *   X | X   X   X   X |
    //        begin -> { *   *   *   X } <- begin + count

    VectorX<Scalar> data_in(PacketSize - 1), data_out(PacketSize - 1);
    data_in.setRandom();
    data_out.setRandom();

    Scalar* aligned_data_in = data_in.data();
    Scalar* aligned_data_out = data_out.data();

    Index begin = 0;
    Index count = PacketSize - 1;

    Packet b = internal::ploadSegment<Packet>(aligned_data_in, begin, count);
    internal::pstoreSegment<Scalar, Packet>(aligned_data_out, b, begin, count);

    verify_data(aligned_data_in, aligned_data_out, b, begin, count);
  }
  static void run() {
    test_unaligned();
    test_aligned();
  }
};

template <typename Scalar, int PacketSize>
struct packet_segment_test_impl<Scalar, PacketSize, false> {
  static void run() {}
};

template <typename Scalar, int PacketSize>
struct packet_segment_test_driver {
  static void run() {
    packet_segment_test_impl<Scalar, PacketSize>::run();
    packet_segment_test_driver<Scalar, PacketSize / 2>::run();
  }
};

template <typename Scalar>
struct packet_segment_test_driver<Scalar, 1> {
  static void run() {}
};

template <typename Scalar>
void test_packet_segment() {
  packet_segment_test_driver<Scalar, internal::packet_traits<Scalar>::size>::run();
}

EIGEN_DECLARE_TEST(packet_segment) {
  for (int i = 0; i < g_repeat; i++) {
    test_packet_segment<bool>();
    test_packet_segment<int8_t>();
    test_packet_segment<uint8_t>();
    test_packet_segment<int16_t>();
    test_packet_segment<uint16_t>();
    test_packet_segment<int32_t>();
    test_packet_segment<uint32_t>();
    test_packet_segment<int64_t>();
    test_packet_segment<uint64_t>();
    test_packet_segment<bfloat16>();
    test_packet_segment<half>();
    test_packet_segment<float>();
    test_packet_segment<double>();
    test_packet_segment<std::complex<float>>();
    test_packet_segment<std::complex<double>>();
  }
}
