"use strict";
// SPDX-License-Identifier: Apache-2.0
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-explicit-any */
require("reflect-metadata");
const ValidationResponse_1 = __importDefault(require("./ValidationResponse"));
const EmptyValue_1 = require("../error/EmptyValue");
const Mapper_1 = __importDefault(require("./Mapper"));
const OptionalDecorator_1 = require("../decorator/OptionalDecorator");
const RuntimeError_1 = require("../error/RuntimeError");
const Validation_1 = require("./Validation");
class ValidatedArgs extends Validation_1.Validation {
    schema;
    constructor(schema) {
        super();
        this.schema = schema;
    }
    validate(key) {
        const vals = [];
        if (!key) {
            const filteredEntries = this.filterSchemaFromProps();
            filteredEntries.forEach((key) => {
                this.pushValidations(key, vals);
            });
        }
        else {
            this.pushValidations(key, vals);
        }
        return vals;
    }
    getOptionalFields() {
        let keys = [];
        keys = Object.keys((0, OptionalDecorator_1.getOptionalFields)(this) ?? {});
        return keys;
    }
    isOptional(key) {
        return this.getOptionalFields().includes(key);
    }
    getProperty(propertyName) {
        if (this[propertyName] === undefined) {
            const privateKeys = {
                dash: `_${String(propertyName)}`,
                hash: `#${String(propertyName)}`,
            };
            if (this[privateKeys.dash]) {
                return this[privateKeys.dash];
            }
            else {
                return this[privateKeys.hash];
            }
        }
        return this[propertyName];
    }
    runValidation(propertyName, val) {
        if (this?.schema[propertyName] && val !== undefined) {
            try {
                const err = this.schema[propertyName]?.(val);
                if (err?.length && err.length > 0) {
                    return new ValidationResponse_1.default(propertyName.toString(), err);
                }
            }
            catch (err) {
                return new ValidationResponse_1.default(propertyName.toString(), [err]);
            }
        }
        else if (this?.schema[propertyName] && !this.isOptional(propertyName) && val === undefined) {
            return new ValidationResponse_1.default(propertyName.toString(), [new EmptyValue_1.EmptyValue(propertyName)]);
        }
        else if (!this?.schema[propertyName] && !this.isOptional(propertyName)) {
            throw new RuntimeError_1.RuntimeError(`Invalid validation schema for property '${propertyName.toString()}'. Did you forget to add the validation?`);
        }
    }
    filterSchemaFromProps() {
        const schemaEntries = Object.keys(this.schema);
        const entries = Mapper_1.default.renamePrivateProps(Object.keys(this));
        const filteredEntries = schemaEntries.filter((value) => entries.includes(value));
        return filteredEntries;
    }
    pushValidations(key, vals) {
        try {
            const err = this.runValidation(key, this.getProperty(key));
            err && vals.push(err);
        }
        catch (err) {
            vals.push(new ValidationResponse_1.default(key.toString(), [err]));
        }
    }
}
exports.default = ValidatedArgs;
