<commit_before>"use strict";

var fs          = require('fs');
var crypto      = require('crypto');
var logger      = require("../libs/utils.js").logger;
var planSchema  = require('../schemas/plan.json');
var chainSchema = require('../schemas/chain.json');
var Ajv         = require('ajv');
var ajv         = new Ajv({allErrors: true});

var Plan        = require("./plan.js");

ajv.addFormat('cron', /^(((([\*]{1}){1})|((\*\/){0,1}(([0-9]{1}){1}|(([1-5]{1}){1}([0-9]{1}){1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([0-9]{1}){1}|(([1]{1}){1}([0-9]{1}){1}){1}|([2]{1}){1}([0-3]{1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([1-9]{1}){1}|(([1-2]{1}){1}([0-9]{1}){1}){1}|([3]{1}){1}([0-1]{1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([1-9]{1}){1}|(([1-2]{1}){1}([0-9]{1}){1}){1}|([3]{1}){1}([0-1]{1}){1}))|(jan|feb|mar|apr|may|jun|jul|aug|sep|okt|nov|dec)) ((([\*]{1}){1})|((\*\/){0,1}(([0-7]{1}){1}))|(sun|mon|tue|wed|thu|fri|sat)))$/);
ajv.addSchema(planSchema, 'planSchema');
ajv.addSchema(chainSchema,'chainSchema');

class FilePlan {
  constructor(filePath){
    this.filePath = filePath;
    this.fileContent;
    this.lastHashPlan;
    this.plan;

    return new Promise((resolve) => {
      var _this = this;
      this.loadFileContent(filePath,'planSchema')
        .then((res) => {
        _this.fileContent = res;
        _this.getChains(res)
          .then((chains) => {
          new Plan('', chains)
            .then(function(plan){
              _this.plan = plan;
              _this.plan.scheduleChains();
              _this.startAutoRefreshBinBackup();
              resolve(_this);
          })
          .catch(function(err){
            logger.log('error','FilePlan new Plan: '+err);
            resolve();
          })
      })
    .catch(function(err){
        logger.log('error','FilePlan loadFileContent getChains: '+err);
        resolve();
      });
  })
  .catch(function(e){
      logger.log('error','File Plan, constructor:'+e)
      resolve(this);
    });
  });
  }

  loadFileContent(filePath, schema){
    var _this = this;
    return new Promise((resolve) => {
        fs.stat(filePath, function(err, res){
        if(err){
          logger.log('error',`File ${filePath} not exists.`, err);
          throw new Error(`File ${filePath} not found.`);
          resolve();
        }else{
          try {
            fs.readFile(filePath, 'utf8', function(err, res){
              if(err){
                logger.log('error',`File loadFileContent (${filePath}) readFile: `+err);
                resolve();
              }else{

                var fileParsed;
                try {
                  fileParsed = JSON.parse(res);
                } catch(err) {
                  var newErr = new Error(`Invalid file (${filePath}), incorrect JSON`);
                  newErr.stack += '\nCaused by: '+err.stack;
                  throw newErr;
                }

                var valid = ajv.validate(schema, fileParsed);

                if (!valid) {
                  logger.log('error',`Invalid file (${filePath}) for schema ${schema}:`,ajv.errors);
                  throw new Error(`Invalid file (${filePath}) for schema ${schema}:`,ajv.errors);
                  resolve();
                }else{
                  resolve(fileParsed);
                }

              }
            });
          } catch(e) {
            throw new Error(`Invalid file (${filePath}), incorrect JSON format: `+e.message,e);
            resolve();
          }
        }
      });
  });
  }

  getChains(json){
    var _this = this;

    return new Promise((resolve) => {

        if(json.hasOwnProperty('chains')){
      if(json.chains instanceof Array){

        var loadChains = [];

        function getAllChains(chain){
          loadChains.push(_this.getChain(chain));
        }

        json.chains.map(getAllChains);

        Promise.all(loadChains)
          .then(function (res) {
            resolve(res);
          })
          .catch(function(e){
            logger.log('error', 'getChains error: ', e);
            reject();
          });

      }else{
        throw new Error('Invalid PlanFile, chain is not an array.');
        resolve();
      }
    }else{
      throw new Error('Invalid PlanFile, chain property not found.');
      resolve();
    }

  });
  };

  getChain(chain){
    var _this = this;
    return new Promise(function(resolve, reject) {

      if (_this.chainIsValid(chain)) {
        resolve(chain);
      } else {
        if (chain.hasOwnProperty('chain_path')) {

          _this.loadFileContent(chain.chain_path,'chainSchema')
            .then((res) => {
            _this.getChain(res)
            .then((res) => {
            resolve(res);
        })
        .catch(function(err){
            logger.log('error', 'External chain error: ', err, chain);
            reject();
          })
        })
        .catch(function(err){
            logger.log('error', 'External chain file error: ', err, chain);
            reject();
          });

        } else {
          logger.log('error', 'Chain ignored, id, name or start_date is not set: ', chain);
          reject();
        }
      }
    });
  }

  chainIsValid(chain){

    var valid = ajv.validate('chainSchema', chain);

    if (!valid) {
      logger.log('error',`Invalid chain ${chain.id} for schema chainSchema:`,ajv.errors);
      return false;
    }else{
      return true;
    }
  };

  refreshBinBackup(){
    var _this = this;
    var plan = _this.plan;

    var objStr = {};//JSON.stringify(plan);

    try {
      objStr = JSON.stringify(plan);
    } catch (e) {
      if (e.message.indexOf('circular') !== -1) {
        logger.log('warn',e);
        logger.log('warn','Retrying stringify plan.');
        try {
          objStr = JSON.stringify(plan);
        } catch (e) {
          if (e.message.indexOf('circular') !== -1) {<commit_msg>REPLACE PROCESS_EXECUTE TO PROCESS_EXEC in samples and Readme<commit_after>"use strict";

var fs          = require('fs');
var crypto      = require('crypto');
var logger      = require("../libs/utils.js").logger;
var planSchema  = require('../schemas/plan.json');
var chainSchema = require('../schemas/chain.json');
var Ajv         = require('ajv');
var ajv         = new Ajv({allErrors: true});

var Plan        = require("./plan.js");

ajv.addFormat('cron', /^(((([\*]{1}){1})|((\*\/){0,1}(([0-9]{1}){1}|(([1-5]{1}){1}([0-9]{1}){1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([0-9]{1}){1}|(([1]{1}){1}([0-9]{1}){1}){1}|([2]{1}){1}([0-3]{1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([1-9]{1}){1}|(([1-2]{1}){1}([0-9]{1}){1}){1}|([3]{1}){1}([0-1]{1}){1}))) ((([\*]{1}){1})|((\*\/){0,1}(([1-9]{1}){1}|(([1-2]{1}){1}([0-9]{1}){1}){1}|([3]{1}){1}([0-1]{1}){1}))|(jan|feb|mar|apr|may|jun|jul|aug|sep|okt|nov|dec)) ((([\*]{1}){1})|((\*\/){0,1}(([0-7]{1}){1}))|(sun|mon|tue|wed|thu|fri|sat)))$/);
ajv.addSchema(planSchema, 'planSchema');
ajv.addSchema(chainSchema,'chainSchema');

class FilePlan {
  constructor(filePath){
    this.filePath = filePath;
    this.fileContent;
    this.lastHashPlan;
    this.plan;

    return new Promise((resolve) => {
      var _this = this;
      this.loadFileContent(filePath,'planSchema')
        .then((res) => {
        _this.fileContent = res;
        _this.getChains(res)
          .then((chains) => {
          new Plan('', chains)
            .then(function(plan){
              _this.plan = plan;
              _this.plan.scheduleChains();
              _this.startAutoRefreshBinBackup();
              resolve(_this);
          })
          .catch(function(err){
            logger.log('error','FilePlan new Plan: '+err);
            resolve();
          })
      })
    .catch(function(err){
        logger.log('error','FilePlan loadFileContent getChains: '+err);
        resolve();
      });
  })
  .catch(function(e){
      logger.log('error','File Plan, constructor:'+e)
      resolve(this);
    });
  });
  }

  loadFileContent(filePath, schema){
    var _this = this;
    return new Promise((resolve) => {
        fs.stat(filePath, function(err, res){
        if(err){
          logger.log('error',`File ${filePath} not exists.`, err);
          throw new Error(`File ${filePath} not found.`);
          resolve();
        }else{
          try {
            fs.readFile(filePath, 'utf8', function(err, res){
              if(err){
                logger.log('error',`File loadFileContent (${filePath}) readFile: `+err);
                resolve();
              }else{

                var fileParsed;
                try {
                  fileParsed = JSON.parse(res);
                } catch(err) {
                  var newErr = new Error(`Invalid file (${filePath}), incorrect JSON`);
                  newErr.stack += '\nCaused by: '+err.stack;
                  throw newErr;
                }

                var valid = ajv.validate(schema, fileParsed);

                if (!valid) {
                  logger.log('error',`Invalid file (${filePath}) for schema ${schema}:`,ajv.errors);
                  throw new Error(`Invalid file (${filePath}) for schema ${schema}:`,ajv.errors);
                  resolve();
                }else{
                  resolve(fileParsed);
                }

              }
            });
          } catch(e) {
            throw new Error(`Invalid file (${filePath}), incorrect JSON format: `+e.message,e);
            resolve();
          }
        }
      });
  });
  }

  getChains(json){
    var _this = this;

    return new Promise((resolve) => {

        if(json.hasOwnProperty('chains')){
      if(json.chains instanceof Array){

        var loadChains = [];

        function getAllChains(chain){
          loadChains.push(_this.getChain(chain));
        }

        json.chains.map(getAllChains);

        Promise.all(loadChains)
          .then(function (res) {
            resolve(res);
          })
          .catch(function(e){
            logger.log('error', 'getChains error: ', e);
            reject();
          });

      }else{
        throw new Error('Invalid PlanFile, chain is not an array.');
        resolve();
      }
    }else{
      throw new Error('Invalid PlanFile, chain property not found.');
      resolve();
    }

  });
  };

  getChain(chain){
    var _this = this;
    return new Promise(function(resolve, reject) {

      if (_this.chainIsValid(chain, true)) {
        resolve(chain);
      } else {
        if (chain.hasOwnProperty('chain_path')) {

          _this.loadFileContent(chain.chain_path,'chainSchema')
            .then((res) => {
            _this.getChain(res)
            .then((res) => {
            resolve(res);
        })
        .catch(function(err){
            logger.log('error', 'External chain error: ', err, chain);
            reject();
          })
        })
        .catch(function(err){
            logger.log('error', 'External chain file error: ', err, chain);
            reject();
          });

        } else {
          logger.log('error', 'Chain ignored, id, name or start_date is not set: ', chain);
          reject();
        }
      }
    });
  }

  chainIsValid(chain, silent){

    var valid = ajv.validate('chainSchema', chain);

    if (!valid) {
      if(!silent) logger.log('error',`Invalid chain, id ${chain.id} for schema chainSchema:`,ajv.errors);
      return false;
    }else{
      return true;
    }
  };

  refreshBinBackup(){
    var _this = this;
    var plan = _this.plan;

    var objStr = {};//JSON.stringify(plan);

    try {
      objStr = JSON.stringify(plan);
    } catch (e) {
      if (e.message.indexOf('circular') !== -1) {
        logger.log('warn',e);
        logger.log('warn','Retrying stringify plan.');
        try {
          objStr = JSON.stringify(plan);
        } catch (e) {
          if (e.message.indexOf('circular') !== -1) {
{'fraction_non_alphanumeric': 0.19877779663894077, 'fraction_numerical': 0.01680529621456459, 'mean_word_length': 1.9875760649087222, 'pattern_counts': {'":': 0, '<': 3, '<?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': '7108599', 'n_tokens_mistral': 3869, 'n_tokens_neox': 3760, 'n_words': 651}