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