// SPDX-License-Identifier: GPL-2.0+
/*
 * BTRFS filesystem implementation for U-Boot
 *
 * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
 */

#include <config.h>
#include <malloc.h>
#include <uuid.h>
#include <linux/time.h>
#include "btrfs.h"
#include "crypto/hash.h"

struct btrfs_info btrfs_info;

static int readdir_callback(const struct btrfs_root *root,
			    struct btrfs_dir_item *item)
{
	static const char typestr[BTRFS_FT_MAX][4] = {
		[BTRFS_FT_UNKNOWN]  = " ? ",
		[BTRFS_FT_REG_FILE] = "   ",
		[BTRFS_FT_DIR]      = "DIR",
		[BTRFS_FT_CHRDEV]   = "CHR",
		[BTRFS_FT_BLKDEV]   = "BLK",
		[BTRFS_FT_FIFO]     = "FIF",
		[BTRFS_FT_SOCK]     = "SCK",
		[BTRFS_FT_SYMLINK]  = "SYM",
		[BTRFS_FT_XATTR]    = " ? ",
	};
	struct btrfs_inode_item inode;
	const char *name = (const char *) (item + 1);
	char filetime[32], *target = NULL;
	time_t mtime;

	if (btrfs_lookup_inode(root, (struct btrfs_key *)&item->location,
			       &inode, NULL)) {
		printf("%s: Cannot find inode item for directory entry %.*s!\n",
		       __func__, item->name_len, name);
		return 0;
	}

	mtime = inode.mtime.sec;
	ctime_r(&mtime, filetime);

	if (item->type == BTRFS_FT_SYMLINK) {
		target = malloc(min(inode.size + 1,
				    (u64) btrfs_info.sb.sectorsize));

		if (target && btrfs_readlink(root, item->location.objectid,
					     target)) {
			free(target);
			target = NULL;
		}

		if (!target)
			printf("%s: Cannot read symlink target!\n", __func__);
	}

	printf("<%s> ", typestr[item->type]);
	if (item->type == BTRFS_FT_CHRDEV || item->type == BTRFS_FT_BLKDEV)
		printf("%4u,%5u  ", (unsigned int) (inode.rdev >> 20),
			(unsigned int) (inode.rdev & 0xfffff));
	else
		printf("%10llu  ", inode.size);

	printf("%24.24s  %.*s", filetime, item->name_len, name);

	if (item->type == BTRFS_FT_SYMLINK) {
		printf(" -> %s", target ? target : "?");
		if (target)
			free(target);
	}

	printf("\n");

	return 0;
}

int btrfs_probe(struct blk_desc *fs_dev_desc,
		struct disk_partition *fs_partition)
{
	btrfs_blk_desc = fs_dev_desc;
	btrfs_part_info = fs_partition;

	memset(&btrfs_info, 0, sizeof(btrfs_info));

	btrfs_hash_init();
	if (btrfs_read_superblock())
		return -1;

	if (btrfs_chunk_map_init()) {
		printf("%s: failed to init chunk map\n", __func__);
		return -1;
	}

	btrfs_info.tree_root.objectid = 0;
	btrfs_info.tree_root.bytenr = btrfs_info.sb.root;
	btrfs_info.chunk_root.objectid = 0;
	btrfs_info.chunk_root.bytenr = btrfs_info.sb.chunk_root;

	if (btrfs_read_chunk_tree()) {
		printf("%s: failed to read chunk tree\n", __func__);
		return -1;
	}

	if (btrfs_find_root(btrfs_get_default_subvol_objectid(),
			    &btrfs_info.fs_root, NULL)) {
		printf("%s: failed to find default subvolume\n", __func__);
		return -1;
	}

	return 0;
}

int btrfs_ls(const char *path)
{
	struct btrfs_root root = btrfs_info.fs_root;
	u64 inr;
	u8 type;

	inr = btrfs_lookup_path(&root, root.root_dirid, path, &type, NULL, 40);

	if (inr == -1ULL) {
		printf("Cannot lookup path %s\n", path);
		return -1;
	}

	if (type != BTRFS_FT_DIR) {
		printf("Not a directory: %s\n", path);
		return -1;
	}

	if (btrfs_readdir(&root, inr, readdir_callback)) {
		printf("An error occured while listing directory %s\n", path);
		return -1;
	}

	return 0;
}

int btrfs_exists(const char *file)
{
	struct btrfs_root root = btrfs_info.fs_root;
	u64 inr;
	u8 type;

	inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, NULL, 40);

	return (inr != -1ULL && type == BTRFS_FT_REG_FILE);
}

int btrfs_size(const char *file, loff_t *size)
{
	struct btrfs_root root = btrfs_info.fs_root;
	struct btrfs_inode_item inode;
	u64 inr;
	u8 type;

	inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, &inode,
				40);

	if (inr == -1ULL) {
		printf("Cannot lookup file %s\n", file);
		return -1;
	}

	if (type != BTRFS_FT_REG_FILE) {
		printf("Not a regular file: %s\n", file);
		return -1;
	}

	*size = inode.size;
	return 0;
}

int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len,
	       loff_t *actread)
{
	struct btrfs_root root = btrfs_info.fs_root;
	struct btrfs_inode_item inode;
	u64 inr, rd;
	u8 type;

	inr = btrfs_lookup_path(&root, root.root_dirid, file, &type, &inode,
				40);

	if (inr == -1ULL) {
		printf("Cannot lookup file %s\n", file);
		return -1;
	}

	if (type != BTRFS_FT_REG_FILE) {
		printf("Not a regular file: %s\n", file);
		return -1;
	}

	if (!len)
		len = inode.size;

	if (len > inode.size - offset)
		len = inode.size - offset;

	rd = btrfs_file_read(&root, inr, offset, len, buf);
	if (rd == -1ULL) {
		printf("An error occured while reading file %s\n", file);
		return -1;
	}

	*actread = rd;
	return 0;
}

void btrfs_close(void)
{
	btrfs_chunk_map_exit();
}

int btrfs_uuid(char *uuid_str)
{
#ifdef CONFIG_LIB_UUID
	uuid_bin_to_str(btrfs_info.sb.fsid, uuid_str, UUID_STR_FORMAT_STD);
	return 0;
#endif
	return -ENOSYS;
}
