/*
 * Copyright © 2011 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>

#include "libdrm_macros.h"
#include "intel_bufmgr.h"
#include "intel_chipset.h"

#define HW_OFFSET 0x12300000

static void
usage(void)
{
	fprintf(stderr, "usage:\n");
	fprintf(stderr, "  test_decode <batch>\n");
	fprintf(stderr, "  test_decode <batch> -dump\n");
	exit(1);
}

static void
read_file(const char *filename, void **ptr, size_t *size)
{
	int fd, ret;
	struct stat st;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		errx(1, "couldn't open `%s'", filename);

	ret = fstat(fd, &st);
	if (ret)
		errx(1, "couldn't stat `%s'", filename);

	*size = st.st_size;
	*ptr = drm_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
	if (*ptr == MAP_FAILED)
		errx(1, "couldn't map `%s'", filename);

	close(fd);
}

static void
dump_batch(struct drm_intel_decode *ctx, const char *batch_filename)
{
	void *batch_ptr;
	size_t batch_size;

	read_file(batch_filename, &batch_ptr, &batch_size);

	drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
					   batch_size / 4);
	drm_intel_decode_set_output_file(ctx, stdout);

	drm_intel_decode(ctx);
}

static void
compare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
{
	FILE *out = NULL;
	void *ptr, *ref_ptr, *batch_ptr;
#ifdef HAVE_OPEN_MEMSTREAM
	size_t size;
#endif
	size_t ref_size, batch_size;
	const char *ref_suffix = "-ref.txt";
	char *ref_filename;

	ref_filename = malloc(strlen(batch_filename) + strlen(ref_suffix) + 1);
	sprintf(ref_filename, "%s%s", batch_filename, ref_suffix);

	/* Read the batch and reference. */
	read_file(batch_filename, &batch_ptr, &batch_size);
	read_file(ref_filename, &ref_ptr, &ref_size);

	/* Set up our decode output in memory, because I don't want to
	 * figure out how to output to a file in a safe and sane way
	 * inside of an automake project's test infrastructure.
	 */
#ifdef HAVE_OPEN_MEMSTREAM
	out = open_memstream((char **)&ptr, &size);
#else
	fprintf(stderr, "platform lacks open_memstream, skipping.\n");
	exit(77);
#endif

	drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
					   batch_size / 4);
	drm_intel_decode_set_output_file(ctx, out);

	drm_intel_decode(ctx);

	if (strcmp(ref_ptr, ptr) != 0) {
		fprintf(stderr, "Decode mismatch with reference `%s'.\n",
			ref_filename);
		fprintf(stderr, "You can dump the new output using:\n");
		fprintf(stderr, "  test_decode \"%s\" -dump\n", batch_filename);
		exit(1);
	}

	fclose(out);
	free(ref_filename);
	free(ptr);
}

static uint16_t
infer_devid(const char *batch_filename)
{
	struct {
		const char *name;
		uint16_t devid;
	} chipsets[] = {
		{ "830",  0x3577},
		{ "855",  0x3582},
		{ "945",  0x2772},
		{ "gen4", 0x2a02 },
		{ "gm45", 0x2a42 },
		{ "gen5", PCI_CHIP_ILD_G },
		{ "gen6", PCI_CHIP_SANDYBRIDGE_GT2 },
		{ "gen7", PCI_CHIP_IVYBRIDGE_GT2 },
		{ "gen8", 0x1616 },
		{ NULL, 0 },
	};
	int i;

	for (i = 0; chipsets[i].name != NULL; i++) {
		if (strstr(batch_filename, chipsets[i].name))
			return chipsets[i].devid;
	}

	fprintf(stderr, "Couldn't guess chipset id from batch filename `%s'.\n",
		batch_filename);
	fprintf(stderr, "Must be contain one of:\n");
	for (i = 0; chipsets[i].name != NULL; i++) {
		fprintf(stderr, "  %s\n", chipsets[i].name);
	}
	exit(1);
}

int
main(int argc, char **argv)
{
	uint16_t devid;
	struct drm_intel_decode *ctx;

	if (argc < 2)
		usage();


	devid = infer_devid(argv[1]);

	ctx = drm_intel_decode_context_alloc(devid);

	if (argc == 3) {
		if (strcmp(argv[2], "-dump") == 0)
			dump_batch(ctx, argv[1]);
		else
			usage();
	} else {
		compare_batch(ctx, argv[1]);
	}

	drm_intel_decode_context_free(ctx);

	return 0;
}
