/* SPDX-License-Identifier: Apache-2.0
 * Copyright(c) 2021 Cisco Systems, Inc.
 */

#include <vppinfra/format.h>
#include <vppinfra/test/test.h>
#include <vppinfra/vector/compress.h>

__test_funct_fn u32
clib_compress_u64_wrapper (u64 *dst, u64 *src, u64 *mask, u32 n_elts)
{
  return clib_compress_u64 (dst, src, mask, n_elts);
}

__test_funct_fn u32
clib_compress_u32_wrapper (u32 *dst, u32 *src, u64 *mask, u32 n_elts)
{
  return clib_compress_u32 (dst, src, mask, n_elts);
}

__test_funct_fn u32
clib_compress_u16_wrapper (u16 *dst, u16 *src, u64 *mask, u32 n_elts)
{
  return clib_compress_u16 (dst, src, mask, n_elts);
}

__test_funct_fn u32
clib_compress_u8_wrapper (u8 *dst, u8 *src, u64 *mask, u32 n_elts)
{
  return clib_compress_u8 (dst, src, mask, n_elts);
}

typedef struct
{
  u64 mask[10];
  u32 n_elts;
} compress_test_t;

static compress_test_t tests[] = {
  { .mask = { 1 }, .n_elts = 1 },
  { .mask = { 2 }, .n_elts = 2 },
  { .mask = { 3 }, .n_elts = 2 },
  { .mask = { 0, 1 }, .n_elts = 66 },
  { .mask = { 0, 2 }, .n_elts = 69 },
  { .mask = { 0, 3 }, .n_elts = 66 },
  { .mask = { ~0ULL, ~0ULL, ~0ULL, ~0ULL }, .n_elts = 62 },
  { .mask = { ~0ULL, ~0ULL, ~0ULL, ~0ULL }, .n_elts = 255 },
  { .mask = { ~0ULL, 1, 1, ~0ULL }, .n_elts = 256 },
};

static clib_error_t *
test_clib_compress_u64 (clib_error_t *err)
{
  u32 i, j;

  for (i = 0; i < ARRAY_LEN (tests); i++)
    {
      compress_test_t *t = tests + i;
      u64 src[t->n_elts];
#ifdef CLIB_SANITIZE_ADDR
      u64 dst[t->n_elts];
#else  /* CLIB_SANITIZE_ADDR */
      u64 dst[513];
#endif /* CLIB_SANITIZE_ADDR */
      u64 *dp = dst;
      u32 r;
      for (j = 0; j < t->n_elts; j++)
	src[j] = j;

      for (j = 0; j < ARRAY_LEN (dst); j++)
	dst[j] = 0xa5a5a5a5a5a5a5a5;

      r = clib_compress_u64_wrapper (dst, src, t->mask, t->n_elts);

      for (j = 0; j < t->n_elts; j++)
	{
	  if ((t->mask[j >> 6] & (1ULL << (j & 0x3f))) == 0)
	    continue;
	  if (dp[0] != src[j])
	    return clib_error_return (err,
				      "wrong data in testcase %u at "
				      "(dst[%u] = 0x%lx, src[%u] = 0x%lx)",
				      i, dp - dst, dp[0], j, src[j]);
	  dp++;
	}

#ifndef CLIB_SANITIZE_ADDR
      if (dst[dp - dst + 1] != 0xa5a5a5a5a5a5a5a5)
	return clib_error_return (err, "buffer overrun in testcase %u", i);
#endif /* CLIB_SANITIZE_ADDR */

      if (dp - dst != r)
	return clib_error_return (err, "wrong number of elts in testcase %u",
				  i);
    }

  return err;
}

static clib_error_t *
test_clib_compress_u32 (clib_error_t *err)
{
  u32 i, j;

  for (i = 0; i < ARRAY_LEN (tests); i++)
    {
      compress_test_t *t = tests + i;
      u32 src[t->n_elts];
#ifdef CLIB_SANITIZE_ADDR
      u32 dst[t->n_elts];
#else  /* CLIB_SANITIZE_ADDR */
      u32 dst[513];
#endif /* CLIB_SANITIZE_ADDR */
      u32 *dp = dst;
      u32 r;
      for (j = 0; j < t->n_elts; j++)
	src[j] = j;

      for (j = 0; j < ARRAY_LEN (dst); j++)
	dst[j] = 0xa5a5a5a5;

      r = clib_compress_u32_wrapper (dst, src, t->mask, t->n_elts);

      for (j = 0; j < t->n_elts; j++)
	{
	  if ((t->mask[j >> 6] & (1ULL << (j & 0x3f))) == 0)
	    continue;

	  if (dp[0] != src[j])
	    return clib_error_return (err,
				      "wrong data in testcase %u at "
				      "(dst[%u] = 0x%x, src[%u] = 0x%x)",
				      i, dp - dst, dp[0], j, src[j]);
	  dp++;
	}

#ifndef CLIB_SANITIZE_ADDR
      if (dst[dp - dst + 1] != 0xa5a5a5a5)
	return clib_error_return (err, "buffer overrun in testcase %u", i);
#endif /* CLIB_SANITIZE_ADDR */

      if (dp - dst != r)
	return clib_error_return (err, "wrong number of elts in testcase %u",
				  i);
    }

  return err;
}

static clib_error_t *
test_clib_compress_u16 (clib_error_t *err)
{
  u32 i, j;

  for (i = 0; i < ARRAY_LEN (tests); i++)
    {
      compress_test_t *t = tests + i;
      u16 src[t->n_elts];
#ifdef CLIB_SANITIZE_ADDR
      u16 dst[t->n_elts];
#else  /* CLIB_SANITIZE_ADDR */
      u16 dst[513];
#endif /* CLIB_SANITIZE_ADDR */
      u16 *dp = dst;
      u32 r;
      for (j = 0; j < t->n_elts; j++)
	src[j] = j;

      for (j = 0; j < ARRAY_LEN (dst); j++)
	dst[j] = 0xa5a5;

      r = clib_compress_u16_wrapper (dst, src, t->mask, t->n_elts);

      for (j = 0; j < t->n_elts; j++)
	{
	  if ((t->mask[j >> 6] & (1ULL << (j & 0x3f))) == 0)
	    continue;
	  if (dp[0] != src[j])
	    return clib_error_return (err,
				      "wrong data in testcase %u at "
				      "(dst[%u] = 0x%x, src[%u] = 0x%x)",
				      i, dp - dst, dp[0], j, src[j]);
	  dp++;
	}

#ifndef CLIB_SANITIZE_ADDR
      if (dst[dp - dst + 1] != 0xa5a5)
	return clib_error_return (err, "buffer overrun in testcase %u", i);
#endif /* CLIB_SANITIZE_ADDR */

      if (dp - dst != r)
	return clib_error_return (err, "wrong number of elts in testcase %u",
				  i);
    }

  return err;
}

static clib_error_t *
test_clib_compress_u8 (clib_error_t *err)
{
  u32 i, j;

  for (i = 0; i < ARRAY_LEN (tests); i++)
    {
      compress_test_t *t = tests + i;
      u8 src[t->n_elts];
#ifdef CLIB_SANITIZE_ADDR
      u8 dst[t->n_elts];
#else  /* CLIB_SANITIZE_ADDR */
      u8 dst[513];
#endif /* CLIB_SANITIZE_ADDR */
      u8 *dp = dst;
      u32 r;
      for (j = 0; j < t->n_elts; j++)
	src[j] = j;

      for (j = 0; j < ARRAY_LEN (dst); j++)
	dst[j] = 0xa5;

      r = clib_compress_u8_wrapper (dst, src, t->mask, t->n_elts);

      for (j = 0; j < t->n_elts; j++)
	{
	  if ((t->mask[j >> 6] & (1ULL << (j & 0x3f))) == 0)
	    continue;
	  if (dp[0] != src[j])
	    return clib_error_return (err,
				      "wrong data in testcase %u at "
				      "(dst[%u] = 0x%x, src[%u] = 0x%x)",
				      i, dp - dst, dp[0], j, src[j]);
	  dp++;
	}

#ifndef CLIB_SANITIZE_ADDR
      if (dst[dp - dst + 1] != 0xa5)
	return clib_error_return (err, "buffer overrun in testcase %u", i);
#endif /* CLIB_SANITIZE_ADDR */

      if (dp - dst != r)
	return clib_error_return (err, "wrong number of elts in testcase %u",
				  i);
    }

  return err;
}

REGISTER_TEST (clib_compress_u64) = {
  .name = "clib_compress_u64",
  .fn = test_clib_compress_u64,
};

REGISTER_TEST (clib_compress_u32) = {
  .name = "clib_compress_u32",
  .fn = test_clib_compress_u32,
};

REGISTER_TEST (clib_compress_u16) = {
  .name = "clib_compress_u16",
  .fn = test_clib_compress_u16,
};

REGISTER_TEST (clib_compress_u8) = {
  .name = "clib_compress_u8",
  .fn = test_clib_compress_u8,
};
