/*
 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program 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; version 2 of the License (not later!)
 *
 * This program 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 program; if not,  see <http://www.gnu.org/licenses>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#define _LARGEFILE64_SOURCE
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <pthread.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>

#include "trace-local.h"

void trace_restore (int argc, char **argv)
{
	struct tracecmd_output *handle;
	const char *output_file = "trace.dat";
	const char *output = NULL;
	const char *input = NULL;
	const char *tracing_dir = NULL;
	const char *kallsyms = NULL;
	struct stat st1;
	struct stat st2;
	int first_arg;
	int create_only = 0;
	int args;
	int c;

	if (argc < 2)
		usage(argv);

	if (strcmp(argv[1], "restore") != 0)
		usage(argv);

	while ((c = getopt(argc-1, argv+1, "+hco:i:t:k:")) >= 0) {
		switch (c) {
		case 'h':
			usage(argv);
			break;
		case 'c':
			if (input)
				die("-c and -i are incompatible");
			create_only = 1;
			/* make output default to partial */
			output_file = "trace-partial.dat";
			break;

		case 't':
			tracing_dir = optarg;
			break;
		case 'k':
			kallsyms = optarg;
			break;
		case 'o':
			if (output)
				die("only one output file allowed");
			output = optarg;
			break;

		case 'i':
			if (input)
				die("only one input file allowed");
			if (create_only)
				die("-c and -i are incompatible");
			input = optarg;
			break;

		default:
			usage(argv);
		}
	}

	if (!output)
		output = output_file;

	if ((argc - optind) <= 1) {
		if (!create_only) {
			warning("No data files found");
			usage(argv);
		}

		handle = tracecmd_create_init_file_override(output, tracing_dir,
							    kallsyms);
		if (!handle)
			die("Unabled to create output file %s", output);
		tracecmd_output_close(handle);
		exit(0);
	}
	first_arg = optind + 1;
	args = argc - first_arg;
	printf("first = %d %s args=%d\n", first_arg, argv[first_arg], args);

	/* Make sure input and output are not the same file */
	if (input && output) {
		if (stat(input, &st1) < 0)
			die("%s:", input);
		/* output exists? otherwise we don't care */
		if (stat(output, &st2) == 0) {
			if (st1.st_ino == st2.st_ino &&
			    st1.st_dev == st2.st_dev)
				die("input and output file are the same");
		}
	}

	if (input) {
		struct tracecmd_input *ihandle;

		ihandle = tracecmd_alloc(input);
		if (!ihandle)
			die("error reading file %s", input);
		/* make sure headers are ok */
		if (tracecmd_read_headers(ihandle) < 0)
			die("error reading file %s headers", input);

		handle = tracecmd_copy(ihandle, output);
		tracecmd_close(ihandle);
	} else
		handle = tracecmd_create_init_file(output);

	if (!handle)
		die("error writing to %s", output);

	if (tracecmd_append_cpu_data(handle, args, &argv[first_arg]) < 0)
		die("failed to append data");

	return;
}
