"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.dataObject = dataObject;
exports.urlObject = urlObject;
exports.fileObject = fileObject;
exports.s3FileObject = s3FileObject;
const clone_1 = __importDefault(require("clone"));
const validator = __importStar(require("./validationWrapper.js"));
const commonUtils = __importStar(require("../utility/common_utils.js"));
const hdbTerms = __importStar(require("../utility/hdbTerms.js"));
const fs = __importStar(require("fs"));
const joi_1 = __importDefault(require("joi"));
const { string } = joi_1.default.types();
const hdbError_ts_1 = require("../utility/errors/hdbError.js");
const { HTTP_STATUS_CODES } = hdbError_ts_1.hdbErrors;
const common_validators_ts_1 = require("./common_validators.js");
const isRequiredString = ' is required';
const actions = ['insert', 'update', 'upsert'];
const constraints = {
    database: {
        presence: false,
        format: common_validators_ts_1.commonValidators.schema_format,
        length: common_validators_ts_1.commonValidators.schema_length,
    },
    schema: {
        presence: false,
        format: common_validators_ts_1.commonValidators.schema_format,
        length: common_validators_ts_1.commonValidators.schema_length,
    },
    table: {
        presence: true,
        format: common_validators_ts_1.commonValidators.schema_format,
        length: common_validators_ts_1.commonValidators.schema_length,
    },
    action: {
        inclusion: {
            within: actions,
            message: 'is required and must be either insert, update, or upsert',
        },
    },
    file_path: {},
    csv_url: {
        url: {
            allowLocal: true,
        },
    },
    data: {},
    passthrough_headers: {},
};
const baseJoiSchema = {
    schema: string.required(),
    table: string.required(),
    action: string.valid('insert', 'update', 'upsert'),
};
const { AWS_ACCESS_KEY, AWS_SECRET, AWS_BUCKET, AWS_FILE_KEY, REGION } = hdbTerms.S3_BUCKET_AUTH_KEYS;
const s3Constraints = {
    s3: {
        presence: true,
    },
    [`s3.${AWS_ACCESS_KEY}`]: {
        presence: true,
        type: 'String',
    },
    [`s3.${AWS_SECRET}`]: {
        presence: true,
        type: 'String',
    },
    [`s3.${AWS_BUCKET}`]: {
        presence: true,
        type: 'String',
    },
    [`s3.${AWS_FILE_KEY}`]: {
        presence: true,
        type: 'String',
        hasValidFileExt: ['.csv', '.json'],
    },
    [`s3.${REGION}`]: {
        presence: true,
        type: 'String',
    },
};
const dataConstraints = (0, clone_1.default)(constraints);
dataConstraints.data.presence = {
    message: isRequiredString,
};
const fileConstraints = (0, clone_1.default)(constraints);
fileConstraints.file_path.presence = {
    message: isRequiredString,
};
const s3FileConstraints = Object.assign((0, clone_1.default)(constraints), s3Constraints);
const urlSchema = (0, clone_1.default)(baseJoiSchema);
urlSchema.csv_url = string.uri().messages({ 'string.uri': "'csv_url' must be a valid url" }).required();
urlSchema.passthrough_headers = joi_1.default.object();
function dataObject(object) {
    let validateRes = validator.validateObject(object, dataConstraints);
    return postValidateChecks(object, validateRes);
}
function urlObject(object) {
    let validateRes = validator.validateBySchema(object, joi_1.default.object(urlSchema));
    return postValidateChecks(object, validateRes);
}
function fileObject(object) {
    let validateRes = validator.validateObject(object, fileConstraints);
    return postValidateChecks(object, validateRes);
}
function s3FileObject(object) {
    let validateRes = validator.validateObject(object, s3FileConstraints);
    return postValidateChecks(object, validateRes);
}
/**
 * Post validate module checks, confirms schema and table exist.
 * If file upload - checks that it exists, permissions and size.
 */
function postValidateChecks(object, validateRes) {
    if (!validateRes) {
        let msg = commonUtils.checkGlobalSchemaTable(object.schema, object.table);
        if (msg) {
            return (0, hdbError_ts_1.handleHDBError)(new Error(), msg, HTTP_STATUS_CODES.BAD_REQUEST);
        }
        if (object.operation === hdbTerms.OPERATIONS_ENUM.CSV_FILE_LOAD) {
            try {
                fs.accessSync(object.file_path, fs.constants.R_OK | fs.constants.F_OK);
            }
            catch (err) {
                if (err.code === hdbTerms.NODE_ERROR_CODES.ENOENT) {
                    return (0, hdbError_ts_1.handleHDBError)(err, `No such file or directory ${err.path}`, HTTP_STATUS_CODES.BAD_REQUEST);
                }
                if (err.code === hdbTerms.NODE_ERROR_CODES.EACCES) {
                    return (0, hdbError_ts_1.handleHDBError)(err, `Permission denied ${err.path}`, HTTP_STATUS_CODES.BAD_REQUEST);
                }
                return (0, hdbError_ts_1.handleHDBError)(err);
            }
        }
    }
    return validateRes;
}
//# sourceMappingURL=fileLoadValidator.js.map