<commit_before>import {Injectable} from "@angular/core";
import {M} from "../m";
import {IdaiFieldDocument} from "./idai-field-document";
import {ConfigLoader} from "idai-components-2/configuration";
import {ProjectConfiguration} from "idai-components-2/documents";

/**
 * @author <NAME>
 * @author <NAME>
 */
@Injectable()
export class Validator {

    private projectConfiguration: ProjectConfiguration;

    constructor(private configLoader: ConfigLoader) {
        
        this.configLoader.configuration().subscribe((result)=>{
            if(result.error == undefined) {
                this.projectConfiguration = result.projectConfiguration;
            } else {
                // TODO Meldung geben/zeigen wenn es ein Problem mit der Configuration gibt
                //this.messages.add(result.error.msgkey);
            }
        });
    }

    /**
     * @param doc
     * @returns {any} the validation report containing the error message as key of m and possibly additional data
     * (e. g. the name of an invalid field)
     */
    public validate(doc: IdaiFieldDocument): any {

        var validationReport = {
            valid: true,
            errorMessage: undefined,
            errorData: []
        };
        
        var resource = doc['resource'];

        if (!this.validateIdentifier(resource)) {
            validationReport.valid = false;
            validationReport.errorMessage = M.VALIDATION_ERROR_IDMISSING;
            return validationReport;
        }

        if (resource.id) {

            if (!this.validateType(resource)) {
                validationReport.valid = false;
                validationReport.errorMessage = M.VALIDATION_ERROR_INVALIDTYPE;
                validationReport.errorData.push(resource.identifier);
                validationReport.errorData.push("\"" + resource.type + "\"");
                return validationReport;
            }

            var invalidFields;
            if (invalidFields = this.validateFields(resource)) {
                validationReport.valid = false;
                validationReport.errorMessage = 
                    invalidFields.length == 1 ? M.VALIDATION_ERROR_INVALIDFIELD : M.VALIDATION_ERROR_INVALIDFIELDS;
                validationReport.errorData.push(resource.type);
                validationReport.errorData.push(invalidFields.join(", "));
                return validationReport;
            }
        }

        return validationReport;
    }

    /**
     * 
     * @param resource
     * @returns {boolean} true if the identifier of the resource is valid, otherwise false
     */
    private validateIdentifier(resource: any): boolean {

        return resource.identifier && resource.identifier.length > 0;
    }

    /**
     * 
     * @param resource
     * @returns {boolean} true if the type of the resource is valid, otherwise false
     */
    private validateType(resource: any): boolean {

        if (!resource.type) return false;

        var types = this.projectConfiguration.getTypesList();

        for (var i in types) {
            if (types[i].name == resource.type) return true;
        }

        return false;
    }

    /**
     * 
     * @param resource
     * @returns {string[]} the names of invalid fields if one ore more of the fields are invalid, otherwise
     * <code>undefined</code>
     */
    private validateFields(resource: any): string[] {

        var projectFields = this.projectConfiguration.getFieldDefinitions(resource.type);
        var relationFields = this.projectConfiguration.getRelationDefinitions(resource.type);


        var defaultFields = [ { name: "id" }, { name: "type" }, { name: "relations" }, { name: "geometries" } ];

        var fields = projectFields.concat(relationFields).concat(defaultFields);

        var invalidFields = [];

        for (var resourceField in resource) {
            if (resource.hasOwnProperty(resourceField)) {
                var fieldFound = false;
                for (var i in fields) {
                    if (fields[i].name == resourceField) {
                        fieldFound = true;
                        break;
                    }
                }
                if (!fieldFound) {
                    invalidFields.push( resourceField );
                }
            }
        }

        if (invalidFields.length > 0)
            return invalidFields;<commit_msg>Add depicts to default fields in validation.<commit_after>import {Injectable} from "@angular/core";
import {M} from "../m";
import {IdaiFieldDocument} from "./idai-field-document";
import {ConfigLoader} from "idai-components-2/configuration";
import {ProjectConfiguration} from "idai-components-2/documents";

/**
 * @author <NAME>
 * @author <NAME>
 */
@Injectable()
export class Validator {

    private projectConfiguration: ProjectConfiguration;

    constructor(private configLoader: ConfigLoader) {
        
        this.configLoader.configuration().subscribe((result)=>{
            if(result.error == undefined) {
                this.projectConfiguration = result.projectConfiguration;
            } else {
                // TODO Meldung geben/zeigen wenn es ein Problem mit der Configuration gibt
                //this.messages.add(result.error.msgkey);
            }
        });
    }

    /**
     * @param doc
     * @returns {any} the validation report containing the error message as key of m and possibly additional data
     * (e. g. the name of an invalid field)
     */
    public validate(doc: IdaiFieldDocument): any {

        var validationReport = {
            valid: true,
            errorMessage: undefined,
            errorData: []
        };
        
        var resource = doc['resource'];

        if (!this.validateIdentifier(resource)) {
            validationReport.valid = false;
            validationReport.errorMessage = M.VALIDATION_ERROR_IDMISSING;
            return validationReport;
        }

        if (resource.id) {

            if (!this.validateType(resource)) {
                validationReport.valid = false;
                validationReport.errorMessage = M.VALIDATION_ERROR_INVALIDTYPE;
                validationReport.errorData.push(resource.identifier);
                validationReport.errorData.push("\"" + resource.type + "\"");
                return validationReport;
            }

            var invalidFields;
            if (invalidFields = this.validateFields(resource)) {
                validationReport.valid = false;
                validationReport.errorMessage = 
                    invalidFields.length == 1 ? M.VALIDATION_ERROR_INVALIDFIELD : M.VALIDATION_ERROR_INVALIDFIELDS;
                validationReport.errorData.push(resource.type);
                validationReport.errorData.push(invalidFields.join(", "));
                return validationReport;
            }
        }

        return validationReport;
    }

    /**
     * 
     * @param resource
     * @returns {boolean} true if the identifier of the resource is valid, otherwise false
     */
    private validateIdentifier(resource: any): boolean {

        return resource.identifier && resource.identifier.length > 0;
    }

    /**
     * 
     * @param resource
     * @returns {boolean} true if the type of the resource is valid, otherwise false
     */
    private validateType(resource: any): boolean {

        if (!resource.type) return false;

        var types = this.projectConfiguration.getTypesList();

        for (var i in types) {
            if (types[i].name == resource.type) return true;
        }

        return false;
    }

    /**
     * 
     * @param resource
     * @returns {string[]} the names of invalid fields if one ore more of the fields are invalid, otherwise
     * <code>undefined</code>
     */
    private validateFields(resource: any): string[] {

        var projectFields = this.projectConfiguration.getFieldDefinitions(resource.type);
        var relationFields = this.projectConfiguration.getRelationDefinitions(resource.type);


        var defaultFields = [
            { name: "id" }, 
            { name: "type" },
            { name: "relations" },
            { name: "depicts" },
            { name: "geometries" } ];

        var fields = projectFields.concat(relationFields).concat(defaultFields);

        var invalidFields = [];

        for (var resourceField in resource) {
            if (resource.hasOwnProperty(resourceField)) {
                var fieldFound = false;
                for (var i in fields) {
                    if (fields[i].name == resourceField) {
                        fieldFound = true;
                        break;
                    }
                }
                if (!fieldFound) {
                    invalidFields.push( resourceField );
                }
            }
        }

        if (invalidFields.length > 0)
            return invalidFields;
{'fraction_non_alphanumeric': 0.09962850388382304, 'fraction_numerical': 0.0011257458065968705, 'mean_word_length': 1.929113089350478, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4295115', 'n_tokens_mistral': 2229, 'n_tokens_neox': 2116, 'n_words': 543}