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

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