/**
 * A user-space application linking to the CPER-JSON conversion library which allows for easy
 * conversion between CPER and CPER-JSON formats. 
 * 
 * Author: Lawrence.Tang@arm.com
 **/

#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <limits.h>
#include "json.h"
#include "../cper-parse.h"
#include "../json-schema.h"

void cper_to_json(char *in_file, char *out_file);
void json_to_cper(char *in_file, char *out_file, char *specification_file,
		  char *program_dir, int no_validate, int debug);
void print_help(void);

int main(int argc, char *argv[])
{
	//Print help if requested.
	if (argc == 2 && strcmp(argv[1], "--help") == 0) {
		print_help();
		return 0;
	}

	//Ensure at least two arguments are present.
	if (argc < 3) {
		printf("Invalid number of arguments. See 'cper-convert --help' for command information.\n");
		return -1;
	}

	//Parse the command line arguments.
	char *input_file = argv[2];
	char *output_file = NULL;
	char *specification_file = NULL;
	int no_validate = 0;
	int debug = 0;
	for (int i = 3; i < argc; i++) {
		if (strcmp(argv[i], "--out") == 0 && i < argc - 1) {
			//Output file.
			output_file = argv[i + 1];
			i++;
		} else if (strcmp(argv[i], "--specification") == 0 &&
			   i < argc - 1) {
			//Specification file.
			specification_file = argv[i + 1];
			i++;
		} else if (strcmp(argv[i], "--no-validate") == 0) {
			//No validation to be used.
			//Invalidates specification file.
			specification_file = NULL;
			no_validate = 1;
		} else if (strcmp(argv[i], "--debug") == 0) {
			//Debug output on.
			debug = 1;
		} else {
			printf("Unrecognised argument '%s'. See 'cper-convert --help' for command information.\n",
			       argv[i]);
		}
	}

	//Run the requested command.
	if (strcmp(argv[1], "to-json") == 0)
		cper_to_json(input_file, output_file);
	else if (strcmp(argv[1], "to-cper") == 0)
		json_to_cper(input_file, output_file, specification_file,
			     argv[0], no_validate, debug);
	else {
		printf("Unrecognised argument '%s'. See 'cper-convert --help' for command information.\n",
		       argv[1]);
		return -1;
	}

	return 0;
}

//Command for converting a provided CPER log file into JSON.
void cper_to_json(char *in_file, char *out_file)
{
	//Get a handle for the log file.
	FILE *cper_file = fopen(in_file, "r");
	if (cper_file == NULL) {
		printf("Could not open provided CPER file '%s', file handle returned null.\n",
		       in_file);
		return;
	}

	//Convert.
	json_object *ir = cper_to_ir(cper_file);
	fclose(cper_file);
	const char *json_output =
		json_object_to_json_string_ext(ir, JSON_C_TO_STRING_PRETTY);

	//Check whether there is a "--out" argument, if there is, then output to file instead.
	//Otherwise, just send to console.
	if (out_file == NULL) {
		printf("%s\n", json_output);
		return;
	}

	//Try to open a file handle to the desired output file.
	FILE *json_file = fopen(out_file, "w");
	if (json_file == NULL) {
		printf("Could not get a handle for output file '%s', file handle returned null.\n",
		       out_file);
		return;
	}

	//Write out to file.
	fwrite(json_output, strlen(json_output), 1, json_file);
	fclose(json_file);
}

//Command for converting a provided CPER-JSON JSON file to CPER binary.
void json_to_cper(char *in_file, char *out_file, char *specification_file,
		  char *program_dir, int no_validate, int debug)
{
	//Verify output file exists.
	if (out_file == NULL) {
		printf("No output file provided for 'to-cper'. See 'cper-convert --help' for command information.\n");
		return;
	}

	//Read JSON IR from file.
	json_object *ir = json_object_from_file(in_file);
	if (ir == NULL) {
		printf("Could not read JSON from file '%s', import returned null.\n",
		       in_file);
		return;
	}

	//Validate the JSON against specification, unless otherwise specified.
	if (!no_validate) {
		int using_default_spec_path = 0;

		//Is there a specification file path?
		if (specification_file == NULL) {
			using_default_spec_path = 1;

			//Make the specification path the assumed default (application directory + specification/cper-json.json).
			specification_file = malloc(PATH_MAX);
			char *dir = dirname(program_dir);
			strcpy(specification_file, dir);
			strcat(specification_file,
			       "/specification/cper-json.json");
		}

		//Enable debug mode if indicated.
		if (debug)
			validate_schema_debug_enable();

		//Attempt to verify with the the specification.
		char *error_message = malloc(JSON_ERROR_MSG_MAX_LEN);
		int success = validate_schema_from_file(specification_file, ir,
							error_message);

		//Free specification path (if necessary).
		if (using_default_spec_path)
			free(specification_file);

		//If failed, early exit before conversion.
		if (!success) {
			printf("JSON format validation failed: %s\n",
			       error_message);
			free(error_message);
			return;
		}
		free(error_message);
	}

	//Attempt a conversion.
	//Open a read for the output file.
	FILE *cper_file = fopen(out_file, "w");
	if (cper_file == NULL) {
		printf("Could not open output file '%s', file handle returned null.\n",
		       out_file);
		return;
	}

	//Run the converter.
	ir_to_cper(ir, cper_file);
	fclose(cper_file);
}

//Command for printing help information.
void print_help(void)
{
	printf(":: to-json cper.file [--out file.name]\n");
	printf("\tConverts the provided CPER log file into JSON, by default writing to stdout. If '--out' is specified,\n");
	printf("\tThe outputted JSON will be written to the provided file name instead.\n");
	printf("\n:: to-cper cper.json --out file.name [--no-validate] [--debug] [--specification some/spec/path.json]\n");
	printf("\tConverts the provided CPER-JSON JSON file into CPER binary. An output file must be specified with '--out'.\n");
	printf("\tBy default, the provided JSON will try to be validated against a specification. If no specification file path\n");
	printf("\tis provided with '--specification', then it will default to 'argv[0] + /specification/cper-json.json'.\n");
	printf("\tIf the '--no-validate' argument is set, then the provided JSON will not be validated. Be warned, this may cause\n");
	printf("\tpremature exit/unexpected behaviour in CPER output.\n");
	printf("\tIf '--debug' is set, then debug output for JSON specification parsing will be printed to stdout.\n");
	printf("\n:: --help\n");
	printf("\tDisplays help information to the console.\n");
}