/*
 * Purple - Internet Messaging Library
 * Copyright (C) Pidgin Developers <devel@pidgin.im>
 *
 * Purple is the legal property of its developers, whose names are too numerous
 * to list here. Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this library; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib.h>

#include <birb.h>

#include <purple.h>

// generated via:
// $ cat test-image.png | hexdump -v -e '1 1 "0x%02x," " "' | xargs -n 8 echo
static gsize test_image_data_len = 160;
static const guint8 test_image_data[] = {
	0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
	0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
	0x08, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xd4, 0x9a,
	0x73, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59,
	0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
	0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00,
	0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe0,
	0x0a, 0x02, 0x16, 0x30, 0x22, 0x28, 0xa4, 0xc9,
	0xdd, 0x00, 0x00, 0x00, 0x1d, 0x69, 0x54, 0x58,
	0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65,
	0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74,
	0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x64, 0x2e,
	0x65, 0x07, 0x00, 0x00, 0x00, 0x16, 0x49, 0x44,
	0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff,
	0x3f, 0x03, 0x03, 0x03, 0xe3, 0xb3, 0x4c, 0xb5,
	0x9b, 0x4e, 0x0b, 0x00, 0x2f, 0xa9, 0x06, 0x2f,
	0x8a, 0xd1, 0xc6, 0xb3, 0x00, 0x00, 0x00, 0x00,
	0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};

/******************************************************************************
 * Helpers
 *****************************************************************************/
static void
test_image(PurpleImage *image, const char *filename,
           const guint8 *expected_data, gsize expected_size)
{
	GBytes *actual_contents = NULL;
	gconstpointer actual_data = NULL;
	gconstpointer contents_data = NULL;
	char *actual_filename = NULL;
	gsize actual_size = 0;
	gsize contents_size = 0;

	birb_assert_type(image, PURPLE_TYPE_IMAGE);

	g_object_get(
		G_OBJECT(image),
		"contents", &actual_contents,
		"data", &actual_data,
		"filename", &actual_filename,
		"size", &actual_size,
		NULL);

	g_assert_cmpmem(actual_data, actual_size,
	                expected_data, expected_size);

	g_assert_nonnull(actual_contents);
	contents_data = g_bytes_get_data(actual_contents, &contents_size);
	g_assert_cmpmem(contents_data, contents_size,
	                expected_data, expected_size);
	g_clear_pointer(&actual_contents, g_bytes_unref);

	g_assert_cmpstr(actual_filename, ==, filename);
	g_clear_pointer(&actual_filename, g_free);

	g_assert_finalize_object(image);
}

/******************************************************************************
 * Tests
 *****************************************************************************/
static void
test_image_new_from_bytes(void) {
	PurpleImage *image = NULL;
	GBytes *contents = NULL;

	contents = g_bytes_new((gconstpointer)test_image_data,
	                       test_image_data_len);

	image = purple_image_new_from_bytes(contents);
	g_clear_pointer(&contents, g_bytes_unref);

	test_image(image, NULL, (gconstpointer)test_image_data,
	           test_image_data_len);
}

static void
test_image_new_from_data(void) {
	PurpleImage *image = NULL;

	image = purple_image_new_from_data(test_image_data, test_image_data_len);

	test_image(image, NULL, (gconstpointer)test_image_data,
	           test_image_data_len);
}

static void
test_image_new_from_filename(void) {
	PurpleImage *image = NULL;
	GError *error = NULL;
	char *filename = NULL;
	char *expected_data = NULL;
	gsize expected_size = 0;

	filename = g_build_filename(TEST_DATA_DIR, "test.png", NULL);
	image = purple_image_new_from_filename(filename, &error);
	g_assert_no_error(error);

	g_file_get_contents(filename, &expected_data, &expected_size, &error);
	g_assert_no_error(error);

	test_image(image, filename, (gconstpointer)expected_data, expected_size);

	g_clear_pointer(&filename, g_free);
	g_clear_pointer(&expected_data, g_free);
}

static void
test_image_new_from_resource(void) {
	PurpleImage *image = NULL;
	GError *error = NULL;

	image = purple_image_new_from_resource("/im/pidgin/libpurple/tests/image/test.png",
	                                       &error);
	g_assert_no_error(error);

	test_image(image, NULL, (gconstpointer)test_image_data,
	           test_image_data_len);
}

/******************************************************************************
 * Main
 *****************************************************************************/
int
main(int argc, char **argv) {
	g_test_init(&argc, &argv, NULL);
	g_test_set_nonfatal_assertions();

	g_test_add_func("/image/new/from-bytes", test_image_new_from_bytes);
	g_test_add_func("/image/new/from-data", test_image_new_from_data);
	g_test_add_func("/image/new/from-filename", test_image_new_from_filename);
	g_test_add_func("/image/new/from-resource", test_image_new_from_resource);

	return g_test_run();
}
