/*
 * 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.
 */

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

#include "config.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 == -1)
		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 = 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;
	size_t size, 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 },
		{ 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;
}
