/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "bcd.h"
#include "compress.h"
#include "fileio.h"
#include "tests.h"
#include "utf8.h"

/* Include the implementation directly, so we can poke at some internals. */
#include "bcd.c"

static void load_bcd(const char *path, void **ret_bcd, size_t *ret_bcd_len) {
        size_t len;
        _cleanup_free_ char *fn = NULL, *compressed = NULL;

        assert_se(get_testdata_dir(path, &fn) >= 0);
        assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, SIZE_MAX, 0, NULL, &compressed, &len) >= 0);
        assert_se(decompress_blob_zstd(compressed, len, ret_bcd, ret_bcd_len, SIZE_MAX) >= 0);
}

static void test_get_bcd_title_one(
                const char *path,
                const char16_t *title_expect,
                size_t title_len_expect) {

        size_t len;
        _cleanup_free_ void *bcd = NULL;

        log_info("/* %s(%s) */", __func__, path);

        load_bcd(path, &bcd, &len);

        char16_t *title = get_bcd_title(bcd, len);
        if (title_expect) {
                assert_se(title);
                assert_se(memcmp(title, title_expect, title_len_expect) == 0);
        } else
                assert_se(!title);
}

TEST(get_bcd_title) {
        test_get_bcd_title_one("test-bcd/win10.bcd.zst", u"Windows 10", sizeof(u"Windows 10"));

        test_get_bcd_title_one("test-bcd/description-bad-type.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/description-empty.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/description-missing.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/description-too-small.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/displayorder-bad-name.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/displayorder-bad-size.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/displayorder-bad-type.bcd.zst", NULL, 0);
        test_get_bcd_title_one("test-bcd/empty.bcd.zst", NULL, 0);
}

TEST(base_block) {
        size_t len;
        BaseBlock backup;
        uint8_t *bcd_base;
        _cleanup_free_ BaseBlock *bcd = NULL;

        load_bcd("test-bcd/win10.bcd.zst", (void **) &bcd, &len);
        backup = *bcd;
        bcd_base = (uint8_t *) bcd;

        assert_se(get_bcd_title(bcd_base, len));

        /* Try various "corruptions" of the base block. */

        assert_se(!get_bcd_title(bcd_base, sizeof(BaseBlock) - 1));

        bcd->sig = 0;
        assert_se(!get_bcd_title(bcd_base, len));
        *bcd = backup;

        bcd->version_minor = 2;
        assert_se(!get_bcd_title(bcd_base, len));
        *bcd = backup;

        bcd->version_major = 4;
        assert_se(!get_bcd_title(bcd_base, len));
        *bcd = backup;

        bcd->type = 1;
        assert_se(!get_bcd_title(bcd_base, len));
        *bcd = backup;

        bcd->primary_seqnum++;
        assert_se(!get_bcd_title(bcd_base, len));
        *bcd = backup;
}

TEST(bad_bcd) {
        size_t len;
        uint8_t *hbins;
        uint32_t offset;
        _cleanup_free_ void *bcd = NULL;

        /* This BCD hive has been manipulated to have bad offsets/sizes at various places. */
        load_bcd("test-bcd/corrupt.bcd.zst", &bcd, &len);

        assert_se(len >= HIVE_CELL_OFFSET);
        hbins = (uint8_t *) bcd + HIVE_CELL_OFFSET;
        len -= HIVE_CELL_OFFSET;
        offset = ((BaseBlock *) bcd)->root_cell_offset;

        const Key *root = get_key(hbins, len, offset, "\0");
        assert_se(root);
        assert_se(!get_key(hbins, sizeof(Key) - 1, offset, "\0"));

        assert_se(!get_key(hbins, len, offset, "\0BadOffset\0"));
        assert_se(!get_key(hbins, len, offset, "\0BadSig\0"));
        assert_se(!get_key(hbins, len, offset, "\0BadKeyNameLen\0"));
        assert_se(!get_key(hbins, len, offset, "\0SubkeyBadOffset\0Dummy\0"));
        assert_se(!get_key(hbins, len, offset, "\0SubkeyBadSig\0Dummy\0"));
        assert_se(!get_key(hbins, len, offset, "\0SubkeyBadNEntries\0Dummy\0"));

        assert_se(!get_key_value(hbins, len, root, "Dummy"));

        const Key *kv_bad_offset = get_key(hbins, len, offset, "\0KeyValuesBadOffset\0");
        assert_se(kv_bad_offset);
        assert_se(!get_key_value(hbins, len, kv_bad_offset, "Dummy"));

        const Key *kv_bad_n_key_values = get_key(hbins, len, offset, "\0KeyValuesBadNKeyValues\0");
        assert_se(kv_bad_n_key_values);
        assert_se(!get_key_value(hbins, len, kv_bad_n_key_values, "Dummy"));

        const Key *kv = get_key(hbins, len, offset, "\0KeyValues\0");
        assert_se(kv);

        assert_se(!get_key_value(hbins, len, kv, "BadOffset"));
        assert_se(!get_key_value(hbins, len, kv, "BadSig"));
        assert_se(!get_key_value(hbins, len, kv, "BadNameLen"));
        assert_se(!get_key_value(hbins, len, kv, "InlineData"));
        assert_se(!get_key_value(hbins, len, kv, "BadDataOffset"));
        assert_se(!get_key_value(hbins, len, kv, "BadDataSize"));
}

TEST(argv_bcds) {
        for (int i = 1; i < saved_argc; i++) {
                size_t len;
                _cleanup_free_ void *bcd = NULL;

                assert_se(read_full_file_full(
                        AT_FDCWD,
                        saved_argv[i],
                        UINT64_MAX,
                        SIZE_MAX,
                        0,
                        NULL,
                        (char **) &bcd,
                        &len) >= 0);

                char16_t *title = get_bcd_title(bcd, len);
                if (title) {
                        _cleanup_free_ char *title_utf8 = utf16_to_utf8(title, char16_strlen(title) * 2);
                        log_info("%s: \"%s\"", saved_argv[i], title_utf8);
                } else
                        log_info("%s: Bad BCD", saved_argv[i]);
        }
}

DEFINE_TEST_MAIN(LOG_INFO);
