/**
 * A very basic, non-complete implementation of a validator for the JSON Schema specification,
 * for validating CPER-JSON.
 * 
 * Author: Lawrence.Tang@arm.com
 **/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <limits.h>
#include <stdarg.h>
#include "json.h"
#include "json-schema.h"
#include "edk/BaseTypes.h"

//Field definitions.
int json_validator_debug = 0;

//Private pre-definitions.
int validate_field(const char *name, json_object *schema, json_object *object,
		   char *error_message);
int validate_integer(const char *field_name, json_object *schema,
		     json_object *object, char *error_message);
int validate_string(const char *field_name, json_object *schema,
		    json_object *object, char *error_message);
int validate_object(const char *field_name, json_object *schema,
		    json_object *object, char *error_message);
int validate_array(const char *field_name, json_object *schema,
		   json_object *object, char *error_message);
void log_validator_error(char *error_message, const char *format, ...);
void log_validator_debug(const char *format, ...);
void log_validator_msg(const char *format, va_list args);

//Validates a single JSON object against a provided schema file, returning 1 on success and 0 on failure to validate.
//Error message space must be allocated prior to call.
int validate_schema_from_file(const char *schema_file, json_object *object,
			      char *error_message)
{
	//Load schema IR from file.
	json_object *schema_ir = json_object_from_file(schema_file);
	if (schema_ir == NULL) {
		log_validator_error(error_message,
				    "Failed to load schema from file '%s'.",
				    schema_file);
		return 0;
	}

	//Get the directory of the file.
	char *schema_file_copy = malloc(strlen(schema_file) + 1);
	strcpy(schema_file_copy, schema_file);
	char *schema_dir = dirname(schema_file_copy);

	int result =
		validate_schema(schema_ir, schema_dir, object, error_message);

	//Free memory from directory call.
	free(schema_file_copy);

	return result;
}

//Validates a single JSON object against a provided schema, returning 1 on success and 0 on failure to validate.
//Error message space must be allocated prior to call.
//If the schema does not include any other sub-schemas using "$ref", then leaving schema_directory as NULL is valid.
int validate_schema(json_object *schema, char *schema_directory,
		    json_object *object, char *error_message)
{
	//Check that the schema version is the same as this validator.
	json_object *schema_ver = json_object_object_get(schema, "$schema");
	if (schema_ver == NULL ||
	    strcmp(json_object_get_string(schema_ver), JSON_SCHEMA_VERSION)) {
		log_validator_error(
			error_message,
			"Provided schema is not of the same version that is referenced by this validator, or is not a schema.");
		return 0;
	}

	//Change current directory into the schema directory.
	char *original_cwd = malloc(PATH_MAX);
	if (getcwd(original_cwd, PATH_MAX) == NULL) {
		log_validator_error(error_message,
				    "Failed fetching the current directory.");
		return 0;
	}
	if (chdir(schema_directory)) {
		log_validator_error(error_message,
				    "Failed to chdir into schema directory.");
		return 0;
	}

	//Parse the top level structure appropriately.
	int result = validate_field("parent", schema, object, error_message);

	//Change back to original CWD.
	chdir(original_cwd);
	free(original_cwd);

	if (result)
		log_validator_debug(
			"Successfully validated the provided object against schema.");
	return result;
}

//Validates a single JSON field given a schema/object.
//Returns -1 on fatal/error failure, 0 on validation failure, and 1 on validation.
int validate_field(const char *field_name, json_object *schema,
		   json_object *object, char *error_message)
{
	log_validator_debug("Validating field '%s'...", field_name);

	//If there is a "$ref" field, attempt to load the referenced schema.
	json_object *ref_schema = json_object_object_get(schema, "$ref");
	if (ref_schema != NULL &&
	    json_object_get_type(ref_schema) == json_type_string) {
		log_validator_debug("$ref schema detected for field '%s'.",
				    field_name);

		//Attempt to load. If loading fails, report error.
		const char *ref_path = json_object_get_string(ref_schema);
		schema = json_object_from_file(ref_path);
		if (schema == NULL) {
			log_validator_error(
				error_message,
				"Failed to open referenced schema file '%s'.",
				ref_path);
			return -1;
		}

		log_validator_debug("loaded schema path '%s' for field '%s'.",
				    ref_path, field_name);
	}

	//Get the schema field type.
	json_object *desired_field_type =
		json_object_object_get(schema, "type");
	if (desired_field_type == NULL ||
	    !json_object_is_type(desired_field_type, json_type_string)) {
		log_validator_error(
			error_message,
			"Desired field type not provided within schema/is not a string for field '%s' (schema violation).",
			field_name);
		return -1;
	}

	//Check the field types are actually equal.
	const char *desired_field_type_str =
		json_object_get_string(desired_field_type);
	if (!((!strcmp(desired_field_type_str, "object") &&
	       json_object_is_type(object, json_type_object)) ||
	      (!strcmp(desired_field_type_str, "array") &&
	       json_object_is_type(object, json_type_array)) ||
	      (!strcmp(desired_field_type_str, "integer") &&
	       json_object_is_type(object, json_type_int)) ||
	      (!strcmp(desired_field_type_str, "string") &&
	       json_object_is_type(object, json_type_string)) ||
	      (!strcmp(desired_field_type_str, "boolean") &&
	       json_object_is_type(object, json_type_boolean)) ||
	      (!strcmp(desired_field_type_str, "double") &&
	       json_object_is_type(object, json_type_double)))) {
		log_validator_error(error_message,
				    "Field type match failed for field '%s'.",
				    field_name);
		return 0;
	}

	//If the schema contains a "oneOf" array, we need to validate the field against each of the
	//possible options in turn.
	json_object *one_of = json_object_object_get(schema, "oneOf");
	if (one_of != NULL && json_object_get_type(one_of) == json_type_array) {
		log_validator_debug("oneOf options detected for field '%s'.",
				    field_name);

		int len = json_object_array_length(one_of);
		int validated = 0;
		for (int i = 0; i < len; i++) {
			//If the "oneOf" member isn't an object, warn on schema violation.
			json_object *one_of_option =
				json_object_array_get_idx(one_of, i);
			if (one_of_option == NULL ||
			    json_object_get_type(one_of_option) !=
				    json_type_object) {
				log_validator_debug(
					"Schema Warning: 'oneOf' member for field '%s' is not an object, schema violation.",
					field_name);
				continue;
			}

			//Validate field with schema.
			validated = validate_field(field_name, one_of_option,
						   object, error_message);
			if (validated == -1)
				return -1;
			if (validated)
				break;
		}

		//Return if failed all checks.
		if (!validated) {
			log_validator_error(
				error_message,
				"No schema object structures matched provided object for field '%s'.",
				field_name);
			return 0;
		}
	}

	//Switch and validate each type in turn.
	switch (json_object_get_type(object)) {
	case json_type_int:
		return validate_integer(field_name, schema, object,
					error_message);
	case json_type_string:
		return validate_string(field_name, schema, object,
				       error_message);
	case json_type_object:
		return validate_object(field_name, schema, object,
				       error_message);
	case json_type_array:
		return validate_array(field_name, schema, object,
				      error_message);

	//We don't perform extra validation on this type.
	default:
		log_validator_debug(
			"validation passed for '%s' (no extra validation).",
			field_name);
		return 1;
	}
}

//Validates a single integer value according to the given specification.
int validate_integer(const char *field_name, json_object *schema,
		     json_object *object, char *error_message)
{
	//Is there a minimum/maximum specified? If so, check those.
	//Validate minimum.
	json_object *min_value = json_object_object_get(schema, "minimum");
	if (min_value != NULL &&
	    json_object_is_type(min_value, json_type_int)) {
		int min_value_int = json_object_get_int(min_value);
		if (json_object_get_uint64(object) < min_value_int) {
			log_validator_error(
				error_message,
				"Failed to validate integer field '%s'. Value was below minimum of %d.",
				field_name, min_value_int);
			return 0;
		}
	}

	//Validate maximum.
	json_object *max_value = json_object_object_get(schema, "maximum");
	if (max_value != NULL &&
	    json_object_is_type(max_value, json_type_int)) {
		int max_value_int = json_object_get_int(max_value);
		if (json_object_get_uint64(object) > max_value_int) {
			log_validator_error(
				error_message,
				"Failed to validate integer field '%s'. Value was above maximum of %d.",
				field_name, max_value_int);
			return 0;
		}
	}

	return 1;
}

//Validates a single string value according to the given specification.
int validate_string(const char *field_name, json_object *schema,
		    json_object *object, char *error_message)
{
	//todo: if there is a "pattern" field, verify the string with RegEx.
	return 1;
}

//Validates a single object value according to the given specification.
int validate_object(const char *field_name, json_object *schema,
		    json_object *object, char *error_message)
{
	//Are there a set of "required" fields? If so, check they all exist.
	json_object *required_fields =
		json_object_object_get(schema, "required");
	if (required_fields != NULL &&
	    json_object_get_type(required_fields) == json_type_array) {
		log_validator_debug(
			"Required fields found for '%s', matching...",
			field_name);

		int len = json_object_array_length(required_fields);
		for (int i = 0; i < len; i++) {
			//Get the required field from schema.
			json_object *required_field =
				json_object_array_get_idx(required_fields, i);
			if (json_object_get_type(required_field) !=
			    json_type_string) {
				log_validator_error(
					error_message,
					"Required field for object '%s' is not a string (schema violation).",
					field_name);
				return 0;
			}

			//Does it exist in the object?
			const char *required_field_str =
				json_object_get_string(required_field);
			if (json_object_object_get(
				    object, required_field_str) == NULL) {
				log_validator_error(
					error_message,
					"Required field '%s' was not present in object '%s'.",
					required_field_str, field_name);
				return 0;
			}
		}
	}

	//Get additional properties value in advance.
	json_object *additional_properties =
		json_object_object_get(schema, "additionalProperties");
	int additional_properties_allowed = 0;
	if (additional_properties != NULL &&
	    json_object_get_type(additional_properties) == json_type_boolean)
		additional_properties_allowed =
			json_object_get_boolean(additional_properties);

	//Run through the "properties" object and validate each of those in turn.
	json_object *properties = json_object_object_get(schema, "properties");
	if (properties != NULL &&
	    json_object_get_type(properties) == json_type_object) {
		json_object_object_foreach(properties, key, value)
		{
			//If the given property name does not exist on the target object, ignore and continue next.
			json_object *object_prop =
				json_object_object_get(object, key);
			if (object_prop == NULL)
				continue;

			//Validate against the schema.
			if (!validate_field(key, value, object_prop,
					    error_message))
				return 0;
		}

		//If additional properties are banned, validate that no additional properties exist.
		if (!additional_properties_allowed) {
			json_object_object_foreach(object, key, value)
			{
				//If the given property name does not exist on the schema object, fail validation.
				json_object *schema_prop =
					json_object_object_get(properties, key);
				if (schema_prop == NULL) {
					log_validator_error(
						error_message,
						"Invalid additional property '%s' detected on field '%s'.",
						key, field_name);
					return 0;
				}
			}
		}
	}

	return 1;
}

//Validates a single array value according to the given specification.
int validate_array(const char *field_name, json_object *schema,
		   json_object *object, char *error_message)
{
	//Iterate all items in the array, and validate according to the "items" schema.
	json_object *items_schema = json_object_object_get(schema, "items");
	if (items_schema != NULL &&
	    json_object_get_type(items_schema) == json_type_object) {
		int array_len = json_object_array_length(object);
		for (int i = 0; i < array_len; i++) {
			if (!validate_field(field_name, items_schema,
					    json_object_array_get_idx(object,
								      i),
					    error_message))
				return 0;
		}
	}

	return 1;
}

//Enables/disables debugging globally for the JSON validator.
void validate_schema_debug_enable()
{
	json_validator_debug = 1;
}
void validate_schema_debug_disable()
{
	json_validator_debug = 0;
}

//Logs an error message to the given error message location and (optionally) provides debug output.
void log_validator_error(char *error_message, const char *format, ...)
{
	va_list args;

	//Log error to error out.
	va_start(args, format);
	vsnprintf(error_message, JSON_ERROR_MSG_MAX_LEN, format, args);
	va_end(args);

	//Debug message if necessary.
	va_start(args, format);
	log_validator_msg(format, args);
	va_end(args);
}

//Logs a debug message to stdout, if validator debug is enabled.
void log_validator_debug(const char *format, ...)
{
	va_list args;
	va_start(args, format);
	log_validator_msg(format, args);
	va_end(args);
}

//Logs a single validator debug/error message.
void log_validator_msg(const char *format, va_list args)
{
	//Print debug output if debug is on.
	if (json_validator_debug) {
		//Make new format string for error.
		const char *header = "json_validator: ";
		char *new_format = malloc(strlen(header) + strlen(format) + 2);
		strcpy(new_format, header);
		strcat(new_format, format);
		strcat(new_format, "\n");

		//Print & free format.
		vfprintf(stdout, new_format, args);
		free(new_format);
	}
}