<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var fs = require('fs'),
path = require('path'),
util = require('util'),
swt = require('swagger-tools').specs.v2,
RefParser = require('json-schema-ref-parser'),
utils = require('./util/utils'),
cwd = process.cwd();

const constraints = ['minLength', 'maxLength', 'minimum', 'maximum', 'enum', 
  'maxItems', 'minItems', 'uniqueItems', 'multipleOf', 'pattern'];
const xmsExamples = 'x-ms-examples', exampleInSpec = 'example-in-spec', BodyParameterValid = 'BODY_PARAMAETER_VALID',
InternalError = 'INTERNAL_ERROR', RefNotFoundError = 'REF_NOTFOUND_ERROR',
JsonParsingError = 'JSON_PARSING_ERROR', XmsExampleNotFoundError = 'X-MS-EXAMPLE_NOTFOUND_ERROR',
ResponseBodyValidationError = 'RESPONSE_BODY_VALIDATION_ERROR',
RequiredParameterNotInExampleError = 'REQUIRED_PARAMETER_NOT_IN_EXAMPLE_ERROR',
BodyParameterValidationError = 'BODY_PARAMETER_VALIDATION_ERROR', TypeValidationError = 'TYPE_VALIDATION_ERROR',
ConstraintValidationError = 'CONSTRAINT_VALIDATION_ERROR', StatuscodeNotInExampleError = 'STATUS_CODE_NOT_IN_EXAMPLE_ERROR';

class SpecValidator {

  constructor(specPath) {
    this.specPath = specPath;
    this.specInJson = null;
    this.refSpecInJson = null;
    this.specValidationResult = { validityStatus: true, operations: {} };
  }

  unifyXmsPaths() {
    //unify x-ms-paths into paths
    if (this.specInJson['x-ms-paths'] && this.specInJson['x-ms-paths'] instanceof Object &&
      Object.keys(this.specInJson['x-ms-paths']).length > 0) {
      let paths = this.specInJson.paths;
      for (let property in this.specInJson['x-ms-paths']) {
        paths[property] = this.specInJson['x-ms-paths'][property];
      }
      this.specInJson.paths = paths;
    }
  }

  updateValidityStatus(value) {
    if (!Boolean(value)) {
      this.specValidationResult.validityStatus = false;
    } else {
      this.specValidationResult.validityStatus = true;
    }
    return;
  }

  constructErrorObject(code, message, innerErrors) {
    let err = {
      code: code,
      message: message,
    }
    if (innerErrors) {
      err.innerErrors = innerErrors;
    }
    this.updateValidityStatus();
    return err;
}

  initialize(options, callback) {
    let self = this;
    if (!callback && typeof options === 'function') {
      callback = options;
      options = {skipInitialization: false};
    }

    if (options && !options.skipInitialization) {
      //process.chdir(path.dirname(self.specPath));
      RefParser.bundle(self.specPath, function(bundleErr, bundleResult){
        if (bundleErr) {
          let msg = `Error occurred in parsing the spec "${self.specPath}". \t${bundleErr.message}.`;
          bundleErr.code = 'PARSE_SPEC_ERROR';
          bundleErr.message = msg;
          self.specValidationResult.resolveSpec = {};
          self.specValidationResult.resolveSpec.error = bundleErr;
          console.log(`${bundleErr.code} - ${bundleErr.message}`);
          self.updateValidityStatus();
          return callback(bundleErr);
        }
        self.specInJson = bundleResult;
        self.unifyXmsPaths();
        RefParser.resolve(self.specInJson, function (err, result) {
          //process.chdir(cwd);
          if (err) {
            let msg = `Error occurred in resolving the spec "${self.specPath}". \t${err.message}.`;
            err.code = 'RESOLVE_SPEC_ERROR';
            err.message = msg;
            self.specValidationResult.resolveSpec = {};
            self.specValidationResult.resolveSpec.error = err;
            console.log(`${err.code} - ${err.message}`);
            self.updateValidityStatus();
            return callback(err);
          }
          self.refSpecInJson = result;
          return callback(null);
        });
      });
    } else {
      return callback(null);
    } 
  }

  //wrapper to validateModel of swagger-tools
  validateModel(modelReference, data) {
    let self = this;
    if (!modelReference) {
      throw new Error('modelReference cannot be null or undefined. It must be of a string. Example: "#/definitions/foo".');
    }
    if (!data) {
      throw new Error('data cannot be null or undefined. It must be of a JSON object or a JSON array.');
    }<commit_msg>check for null and undefined explicitly.<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var fs = require('fs'),
path = require('path'),
util = require('util'),
swt = require('swagger-tools').specs.v2,
RefParser = require('json-schema-ref-parser'),
utils = require('./util/utils'),
cwd = process.cwd();

const constraints = ['minLength', 'maxLength', 'minimum', 'maximum', 'enum', 
  'maxItems', 'minItems', 'uniqueItems', 'multipleOf', 'pattern'];
const xmsExamples = 'x-ms-examples', exampleInSpec = 'example-in-spec', BodyParameterValid = 'BODY_PARAMAETER_VALID',
InternalError = 'INTERNAL_ERROR', RefNotFoundError = 'REF_NOTFOUND_ERROR',
JsonParsingError = 'JSON_PARSING_ERROR', XmsExampleNotFoundError = 'X-MS-EXAMPLE_NOTFOUND_ERROR',
ResponseBodyValidationError = 'RESPONSE_BODY_VALIDATION_ERROR',
RequiredParameterNotInExampleError = 'REQUIRED_PARAMETER_NOT_IN_EXAMPLE_ERROR',
BodyParameterValidationError = 'BODY_PARAMETER_VALIDATION_ERROR', TypeValidationError = 'TYPE_VALIDATION_ERROR',
ConstraintValidationError = 'CONSTRAINT_VALIDATION_ERROR', StatuscodeNotInExampleError = 'STATUS_CODE_NOT_IN_EXAMPLE_ERROR';

class SpecValidator {

  constructor(specPath) {
    this.specPath = specPath;
    this.specInJson = null;
    this.refSpecInJson = null;
    this.specValidationResult = { validityStatus: true, operations: {} };
  }

  unifyXmsPaths() {
    //unify x-ms-paths into paths
    if (this.specInJson['x-ms-paths'] && this.specInJson['x-ms-paths'] instanceof Object &&
      Object.keys(this.specInJson['x-ms-paths']).length > 0) {
      let paths = this.specInJson.paths;
      for (let property in this.specInJson['x-ms-paths']) {
        paths[property] = this.specInJson['x-ms-paths'][property];
      }
      this.specInJson.paths = paths;
    }
  }

  updateValidityStatus(value) {
    if (!Boolean(value)) {
      this.specValidationResult.validityStatus = false;
    } else {
      this.specValidationResult.validityStatus = true;
    }
    return;
  }

  constructErrorObject(code, message, innerErrors) {
    let err = {
      code: code,
      message: message,
    }
    if (innerErrors) {
      err.innerErrors = innerErrors;
    }
    this.updateValidityStatus();
    return err;
}

  initialize(options, callback) {
    let self = this;
    if (!callback && typeof options === 'function') {
      callback = options;
      options = {skipInitialization: false};
    }

    if (options && !options.skipInitialization) {
      //process.chdir(path.dirname(self.specPath));
      RefParser.bundle(self.specPath, function(bundleErr, bundleResult){
        if (bundleErr) {
          let msg = `Error occurred in parsing the spec "${self.specPath}". \t${bundleErr.message}.`;
          bundleErr.code = 'PARSE_SPEC_ERROR';
          bundleErr.message = msg;
          self.specValidationResult.resolveSpec = {};
          self.specValidationResult.resolveSpec.error = bundleErr;
          console.log(`${bundleErr.code} - ${bundleErr.message}`);
          self.updateValidityStatus();
          return callback(bundleErr);
        }
        self.specInJson = bundleResult;
        self.unifyXmsPaths();
        RefParser.resolve(self.specInJson, function (err, result) {
          //process.chdir(cwd);
          if (err) {
            let msg = `Error occurred in resolving the spec "${self.specPath}". \t${err.message}.`;
            err.code = 'RESOLVE_SPEC_ERROR';
            err.message = msg;
            self.specValidationResult.resolveSpec = {};
            self.specValidationResult.resolveSpec.error = err;
            console.log(`${err.code} - ${err.message}`);
            self.updateValidityStatus();
            return callback(err);
          }
          self.refSpecInJson = result;
          return callback(null);
        });
      });
    } else {
      return callback(null);
    } 
  }

  //wrapper to validateModel of swagger-tools
  validateModel(modelReference, data) {
    let self = this;
    if (!modelReference) {
      throw new Error('modelReference cannot be null or undefined. It must be of a string. Example: "#/definitions/foo".');
    }
    if (data === null || data === undefined) {
      throw new Error('data cannot be null or undefined.');
    }
{'fraction_non_alphanumeric': 0.12896916705016107, 'fraction_numerical': 0.0004601932811780948, 'mean_word_length': 3.1974891356832447, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '311875', 'n_tokens_mistral': 2592, 'n_tokens_neox': 2556, 'n_words': 549}