/*
 * BSD 3-Clause New License (https://spdx.org/licenses/BSD-3-Clause.html)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 2016-2018, Klara Inc.
 * Copyright (c) 2016-2018, Allan Jude
 * Copyright (c) 2018-2020, Sebastian Gottschall
 * Copyright (c) 2019-2020, Michael Niewöhner
 * Copyright (c) 2020, The FreeBSD Foundation [1]
 *
 * [1] Portions of this software were developed by Allan Jude
 *     under sponsorship from the FreeBSD Foundation.
 */

#ifndef	_ZFS_ZSTD_H
#define	_ZFS_ZSTD_H

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * ZSTD block header
 * NOTE: all fields in this header are in big endian order.
 */
typedef struct zfs_zstd_header {
	/* Compressed size of data */
	uint32_t c_len;

	/*
	 * Version and compression level
	 * We used to use a union to reference compression level
	 * and version easily, but as it turns out, relying on the
	 * ordering of bitfields is not remotely portable.
	 * So now we have get/set functions in zfs_zstd.c for
	 * manipulating this in just the right way forever.
	 */
	uint32_t raw_version_level;
	char data[];
} zfs_zstdhdr_t;

/*
 * Simple struct to pass the data from raw_version_level around.
 */
typedef struct zfs_zstd_meta {
	uint8_t level;
	uint32_t version;
} zfs_zstdmeta_t;

/*
 * kstat helper macros
 */
#define	ZSTDSTAT(stat)		(zstd_stats.stat.value.ui64)
#define	ZSTDSTAT_ADD(stat, val) \
	atomic_add_64(&zstd_stats.stat.value.ui64, (val))
#define	ZSTDSTAT_SUB(stat, val) \
	atomic_sub_64(&zstd_stats.stat.value.ui64, (val))
#define	ZSTDSTAT_BUMP(stat)	ZSTDSTAT_ADD(stat, 1)

/* (de)init for user space / kernel emulation */
int zstd_init(void);
void zstd_fini(void);

size_t zfs_zstd_compress(void *s_start, void *d_start, size_t s_len,
    size_t d_len, int level);
int zfs_zstd_get_level(void *s_start, size_t s_len, uint8_t *level);
int zfs_zstd_decompress_level(void *s_start, void *d_start, size_t s_len,
    size_t d_len, uint8_t *level);
int zfs_zstd_decompress(void *s_start, void *d_start, size_t s_len,
    size_t d_len, int n);
void zfs_zstd_cache_reap_now(void);

/*
 * So, the reason we have all these complicated set/get functions is that
 * originally, in the zstd "header" we wrote out to disk, we used a 32-bit
 * bitfield to store the "level" (8 bits) and "version" (24 bits).
 *
 * Unfortunately, bitfields make few promises about how they're arranged in
 * memory...
 *
 * By way of example, if we were using version 1.4.5 and level 3, it'd be
 * level = 0x03, version = 10405/0x0028A5, which gets broken into Vhigh = 0x00,
 * Vmid = 0x28, Vlow = 0xA5. We include these positions below to help follow
 * which data winds up where.
 *
 * As a consequence, we wound up with little endian platforms with a layout
 * like this in memory:
 *
 *      0       8      16      24      32
 *      +-------+-------+-------+-------+
 *      | Vlow  | Vmid  | Vhigh | level |
 *      +-------+-------+-------+-------+
 *        =A5     =28     =00     =03
 *
 * ...and then, after being run through BE_32(), serializing this out to
 * disk:
 *
 *      0       8      16      24      32
 *      +-------+-------+-------+-------+
 *      | level | Vhigh | Vmid  | Vlow  |
 *      +-------+-------+-------+-------+
 *        =03     =00     =28     =A5
 *
 * while on big-endian systems, since BE_32() is a noop there, both in
 * memory and on disk, we wind up with:
 *
 *      0       8      16      24      32
 *      +-------+-------+-------+-------+
 *      | Vhigh | Vmid  | Vlow  | level |
 *      +-------+-------+-------+-------+
 *        =00     =28     =A5     =03
 *
 * (Vhigh is always 0 until version exceeds 6.55.35. Vmid and Vlow are the
 * other two bytes of the "version" data.)
 *
 * So now we use the BF32_SET macros to get consistent behavior (the
 * ondisk LE encoding, since x86 currently rules the world) across
 * platforms, but the "get" behavior requires that we check each of the
 * bytes in the aforementioned former-bitfield for 0x00, and from there,
 * we can know which possible layout we're dealing with. (Only the two
 * that have been observed in the wild are illustrated above, but handlers
 * for all 4 positions of 0x00 are implemented.
 */

static inline void
zfs_get_hdrmeta(const zfs_zstdhdr_t *blob, zfs_zstdmeta_t *res)
{
	uint32_t raw = blob->raw_version_level;
	uint8_t findme = 0xff;
	int shift;
	for (shift = 0; shift < 4; shift++) {
		findme = BF32_GET(raw, 8*shift, 8);
		if (findme == 0)
			break;
	}
	switch (shift) {
	case 0:
		res->level = BF32_GET(raw, 24, 8);
		res->version = BSWAP_32(raw);
		res->version = BF32_GET(res->version, 8, 24);
		break;
	case 1:
		res->level = BF32_GET(raw, 0, 8);
		res->version = BSWAP_32(raw);
		res->version = BF32_GET(res->version, 0, 24);
		break;
	case 2:
		res->level = BF32_GET(raw, 24, 8);
		res->version = BF32_GET(raw, 0, 24);
		break;
	case 3:
		res->level = BF32_GET(raw, 0, 8);
		res->version = BF32_GET(raw, 8, 24);
		break;
	default:
		res->level = 0;
		res->version = 0;
		break;
	}
}

static inline uint8_t
zfs_get_hdrlevel(const zfs_zstdhdr_t *blob)
{
	uint8_t level = 0;
	zfs_zstdmeta_t res;
	zfs_get_hdrmeta(blob, &res);
	level = res.level;
	return (level);
}

static inline uint32_t
zfs_get_hdrversion(const zfs_zstdhdr_t *blob)
{
	uint32_t version = 0;
	zfs_zstdmeta_t res;
	zfs_get_hdrmeta(blob, &res);
	version = res.version;
	return (version);

}

static inline void
zfs_set_hdrversion(zfs_zstdhdr_t *blob, uint32_t version)
{
	/* cppcheck-suppress syntaxError */
	BF32_SET(blob->raw_version_level, 0, 24, version);
}

static inline void
zfs_set_hdrlevel(zfs_zstdhdr_t *blob, uint8_t level)
{
	/* cppcheck-suppress syntaxError */
	BF32_SET(blob->raw_version_level, 24, 8, level);
}


#ifdef	__cplusplus
}
#endif

#endif /* _ZFS_ZSTD_H */
