// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
/*
 * Copyright (C), 2008-2021, OPPO Mobile Comm Corp., Ltd.
 * Created by Huang Jianan <huangjianan@oppo.com>
 */
#include <string.h>
#include <stdlib.h>
#include "erofs/err.h"
#include "erofs/list.h"
#include "erofs/print.h"
#include "erofs/compress_hints.h"

static LIST_HEAD(compress_hints_head);

static void dump_regerror(int errcode, const char *s, const regex_t *preg)
{
	char str[512];

	regerror(errcode, preg, str, sizeof(str));
	erofs_err("invalid regex %s (%s)\n", s, str);
}

/* algorithmtype is actually ccfg # here */
static int erofs_insert_compress_hints(const char *s, unsigned int blks,
				       unsigned int algorithmtype)
{
	struct erofs_compress_hints *ch;
	int ret;

	ch = malloc(sizeof(struct erofs_compress_hints));
	if (!ch)
		return -ENOMEM;

	ret = regcomp(&ch->reg, s, REG_EXTENDED|REG_NOSUB);
	if (ret) {
		dump_regerror(ret, s, &ch->reg);
		free(ch);
		return ret;
	}
	ch->physical_clusterblks = blks;
	ch->algorithmtype = algorithmtype;

	list_add_tail(&ch->list, &compress_hints_head);
	erofs_info("compress hint %s (%u) is inserted", s, blks);
	return ret;
}

bool z_erofs_apply_compress_hints(struct erofs_inode *inode)
{
	const char *s;
	struct erofs_compress_hints *r;
	unsigned int pclusterblks, algorithmtype;

	if (inode->z_physical_clusterblks)
		return true;

	s = erofs_fspath(inode->i_srcpath);
	pclusterblks = cfg.c_pclusterblks_def;
	algorithmtype = 0;

	list_for_each_entry(r, &compress_hints_head, list) {
		int ret = regexec(&r->reg, s, (size_t)0, NULL, 0);

		if (!ret) {
			pclusterblks = r->physical_clusterblks;
			algorithmtype = r->algorithmtype;
			break;
		}
		if (ret != REG_NOMATCH)
			dump_regerror(ret, s, &r->reg);
	}
	inode->z_physical_clusterblks = pclusterblks;
	inode->z_algorithmtype[0] = algorithmtype;

	/* pclusterblks is 0 means this file shouldn't be compressed */
	return pclusterblks != 0;
}

void erofs_cleanup_compress_hints(void)
{
	struct erofs_compress_hints *r, *n;

	list_for_each_entry_safe(r, n, &compress_hints_head, list) {
		list_del(&r->list);
		free(r);
	}
}

int erofs_load_compress_hints(void)
{
	char buf[PATH_MAX + 100];
	FILE *f;
	unsigned int line, max_pclustersize = 0;
	int ret = 0;

	if (!cfg.c_compress_hints_file)
		return 0;

	f = fopen(cfg.c_compress_hints_file, "r");
	if (!f)
		return -errno;

	for (line = 1; fgets(buf, sizeof(buf), f); ++line) {
		unsigned int pclustersize, ccfg;
		char *alg, *pattern;

		if (*buf == '#' || *buf == '\n')
			continue;

		pclustersize = atoi(strtok(buf, "\t "));
		alg = strtok(NULL, "\n\t ");
		pattern = strtok(NULL, "\n");
		if (!pattern) {
			pattern = alg;
			alg = NULL;
		}
		if (!pattern || *pattern == '\0') {
			erofs_err("cannot find a match pattern at line %u",
				  line);
			ret = -EINVAL;
			goto out;
		}
		if (!alg || *alg == '\0') {
			ccfg = 0;
		} else {
			ccfg = atoi(alg);
			if (ccfg >= EROFS_MAX_COMPR_CFGS ||
			    !cfg.c_compr_alg[ccfg]) {
				erofs_err("invalid compressing configuration \"%s\" at line %u",
					  alg, line);
				ret = -EINVAL;
				goto out;
			}
		}

		if (pclustersize % EROFS_BLKSIZ) {
			erofs_warn("invalid physical clustersize %u, "
				   "use default pclusterblks %u",
				   pclustersize, cfg.c_pclusterblks_def);
			continue;
		}
		erofs_insert_compress_hints(pattern,
					    pclustersize / EROFS_BLKSIZ, ccfg);

		if (pclustersize > max_pclustersize)
			max_pclustersize = pclustersize;
	}

	if (cfg.c_pclusterblks_max * EROFS_BLKSIZ < max_pclustersize) {
		cfg.c_pclusterblks_max = max_pclustersize / EROFS_BLKSIZ;
		erofs_warn("update max pclusterblks to %u", cfg.c_pclusterblks_max);
	}
out:
	fclose(f);
	return ret;
}
