/**
 * 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 <libcper/json-schema.h>
#include <libcper/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, const 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);
	json_object_put(schema_ir);

	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) != 0) {
		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.");
		if (original_cwd) {
			free(original_cwd);
		}
		return 0;
	}
	if (chdir(schema_directory)) {
		log_validator_error(error_message,
				    "Failed to chdir into schema directory.");
		if (original_cwd) {
			free(original_cwd);
		}
		return 0;
	}

	//Parse the top level structure appropriately.
	int result = validate_field("parent", schema, object, error_message);
	if (result < 0) {
		log_validator_error(error_message,
				    "Failed validating schema for parent.");
		result = 0;
	}

	//Change back to original CWD.
	if (chdir(original_cwd)) {
		log_validator_error(error_message,
				    "Failed to chdir into original directory.");
	}

	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)
{
	int ret = -1;

	log_validator_debug("Validating field '%s'...", field_name);

	//If there is a "$ref" field, attempt to load the referenced schema.
	json_object *ref_field = json_object_object_get(schema, "$ref");
	if (ref_field != NULL &&
	    json_object_get_type(ref_field) == 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_field);
		json_object *ref_schema = json_object_from_file(ref_path);
		if (ref_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);

		//Validate field with schema.
		ret = validate_field(field_name, ref_schema, object,
				     error_message);
		json_object_put(ref_schema);

		return ret;
	}

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

	//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) < (uint64_t)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) > (uint64_t)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, const char *error_message)
{
	//todo: if there is a "pattern" field, verify the string with RegEx.
	(void)field_name;
	(void)schema;
	(void)object;
	(void)error_message;

	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)
			{
				//Avoid compiler warning
				(void)value;

				//If the given property name does not exist on the schema object, fail validation.
				const 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);
	}
}
