/**
 * 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 <libcper/cper-parse.h>
#include <libcper/json-schema.h>

void cper_to_json(char *in_file, char *out_file, int is_single_section);
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, 0);
	} else if (strcmp(argv[1], "to-json-section") == 0) {
		cper_to_json(input_file, output_file, 1);
	} 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 or CPER single section file into JSON.
void cper_to_json(char *in_file, char *out_file, int is_single_section)
{
	//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;
	if (is_single_section) {
		ir = cper_single_section_to_ir(cper_file);
	} else {
		ir = cper_to_ir(cper_file);
	}
	fclose(cper_file);

	//Output to string.
	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);
	}

	//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;
	}

	//Detect the type of CPER (full log, single section) from the IR given.
	//Run the converter accordingly.
	if (json_object_object_get(ir, "header") != NULL) {
		ir_to_cper(ir, cper_file);
	} else {
		ir_single_section_to_cper(ir, cper_file);
	}
	fclose(cper_file);
	json_object_put(ir);
}

//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-json-section cper.section.file [--out file.name]\n");
	printf("\tConverts the provided single CPER section descriptor & section file into JSON, by default writing to stdout.\n");
	printf("\tOtherwise behaves the same as 'to-json'.\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("\tWill automatically detect whether the JSON passed is a single section, or a whole file,\n");
	printf("\tand output binary accordingly.\n\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\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");
}
