'use strict';

// GLOBAL
const path = require('path');
const glob = require('glob');

// LOCAL
const tools = require('../../utils/tools');
const notificationUtils = require('../../utils/notification/notification-utils');
const configUtils = require('../config/config-utils');
const metadataUtils = require('../metadata/metadata-utils');
const installUtils = require('../install/install-utils');

const runStylesAudit = (module.exports.runStylesAudit = (pkg, customPath) => {
  const generateIndicesContent = (indices, file, fileContent, exclusions = []) => {
    let content = [];

    indices.forEach((i) => {
      for (var pos = i - 1; pos >= 0; pos--) {
        if (fileContent.charAt(pos) === '\n') {
          break;
        }
      }
      const remaining = fileContent.substring(pos + 1).trim();
      const breakPos = remaining.indexOf('\n');
      const indiceContent = remaining.substring(0, breakPos - 1);

      const lineNumber = fileContent.substring(0, i).split('\n').length;

      let excluded = false;
      exclusions.forEach((exclusion) => {
        if (indiceContent.indexOf(exclusion) > -1) {
          excluded = true;
        }
        if (indiceContent === '') {
          excluded = true;
        }
      });

      if (!excluded) {
        content.push({
          file: file,
          lineNumber: lineNumber,
          content: indiceContent,
        });
      }
    });

    return content;
  };

  const recalculateIndicesCount = (indicesContent) => {
    let count = 0;

    if (indicesContent && indicesContent.length !== 0) {
      indicesContent.forEach((ic) => {
        count++;
      });
    }

    return count;
  };

  const getStatus = (count) => {
    return count > 5 ? 'CRITICAL' : count > 0 && count <= 5 ? 'IMPROVE' : 'OK';
  };

  // checking params

  let srcPath;

  if (customPath) {
    srcPath = customPath;
    tools.logTitle(`Auditing : ${customPath}`);
  } else {
    if (pkg.srcRootDefault) {
      srcPath = pkg.paths.src;
    } else {
      if (pkg.standalone) {
        srcPath = pkg.paths.src;
      } else {
        srcPath = pkg.paths.root;
      }
    }
    tools.logTitle(`Auditing : ${pkg.name}`);
  }

  // setting default report object

  const report = {
    package: null,
    score: 0,
    total: 0,
    pcScore: 0,
    scssFilesCount: 0,
    scssEmptyFiles: 0,
    htmlFilesCount: 0,
    htmlLinesCount: 0,
    scssLinescount: 0,
    stylesAuditDisabledCount: 0,
    tsOver500: {
      count: 0,
      files: [],
    },
    tsNotSoC: {
      count: 0,
      files: [],
      templateCount: 0,
      styleCount: 0,
    },
    thirdPartyDependencies: {
      count: 0,
      dependencies: [],
    },
    euiOverrides: {
      count: 0,
      indices: [],
    },
    sizesPxEm: {
      count: 0,
      indices: [],
    },
    boxShadow: {
      count: 0,
      indices: [],
    },
    fontFamily: {
      count: 0,
      indices: [],
    },
    important: {
      count: 0,
      indices: [],
    },
    plainColors: {
      count: 0,
      indices: [],
    },
    ngDeep: {
      count: 0,
      indices: [],
    },
    zIndex: {
      count: 0,
      indices: [],
    },
    inlineStyles: {
      count: 0,
      indices: [],
    },
    material: {
      count: 0,
      indices: [],
    },
    primeng: {
      count: 0,
      indices: [],
    },
    allModules: {
      count: 0,
      indices: [],
    },
    uxCmp: {
      count: 0,
      indices: [],
    },
    mywpSharedAll: {
      count: 0,
      indices: [],
    },
    finalReport: {},
  };

  if (customPath) {
    report.package = customPath;
  } else {
    report.package = pkg.name;
  }


  let files;

  // CHECKING TS FILES CONTENT
  // -------------------------

  files = glob.sync('**/*.ts', { cwd: srcPath, nodir: true, follow: true, dot: true });

  files.forEach((file) => {
    let result, regex;

    const filePath = path.join(srcPath, file);
    const fileContent = tools.getFileContent(filePath);
    const linesCount = fileContent.split('\n').length;

    if (fileContent.indexOf('styles-audit-disabled') !== -1) {
      report.stylesAuditDisabledCount++;
      return;
    }

    if (linesCount > 500) {
      report.tsOver500.count++;
      report.tsOver500.files.push(file);
    }

    let tsNotSoCTemplateIndices = [];
    regex = /template:/gi;
    while ((result = regex.exec(fileContent))) {
      tsNotSoCTemplateIndices.push(result.index);
    }
    report.tsNotSoC.count += tsNotSoCTemplateIndices.length;
    report.tsNotSoC.templateCount += tsNotSoCTemplateIndices.length;
    if (tsNotSoCTemplateIndices.length > 0) {
      report.tsNotSoC.files.push(file);
    }

    let tsNotSoCStyleIndices = [];
    regex = /styles:/gi;
    while ((result = regex.exec(fileContent))) {
      tsNotSoCStyleIndices.push(result.index);
    }
    report.tsNotSoC.count += tsNotSoCStyleIndices.length;
    report.tsNotSoC.styleCount += tsNotSoCStyleIndices.length;
    if (tsNotSoCStyleIndices.length > 0) {
      report.tsNotSoC.files.push(file);
    }

    report.tsNotSoC.files = tools.removeArrayDuplicates(report.tsNotSoC.files);


    let primengIndices = [];
    regex = /primeng/gi;
    while ((result = regex.exec(fileContent))) {
      primengIndices.push(result.index);
    }
    report.primeng.count += primengIndices.length;
    report.primeng.indices = [...report.primeng.indices, ...generateIndicesContent(primengIndices, file, fileContent)];

    let materialIndices = [];
    regex = /@angular\/material/gi;
    while ((result = regex.exec(fileContent))) {
      materialIndices.push(result.index);
    }
    const indicesContent = generateIndicesContent(materialIndices, file, fileContent, [
      '@angular/material/core',
      '@angular/material-moment-adapter',
    ]);

    report.material.count += recalculateIndicesCount(indicesContent);
    report.material.indices = [...report.material.indices, ...indicesContent];

    let allModulesIndices = [];
    regex = /EuiAllModule/gi;
    while ((result = regex.exec(fileContent))) {
      allModulesIndices.push(result.index);
    }
    regex = /UxAllModule/gi;
    while ((result = regex.exec(fileContent))) {
      allModulesIndices.push(result.index);
    }
    report.allModules.count += allModulesIndices.length;
    report.allModules.indices = [...report.allModules.indices, ...generateIndicesContent(allModulesIndices, file, fileContent)];

    let mywpSharedAllIndices = [];
    regex = /\@mywp\/shared'|\@mywp\/shared"/gi;
    while ((result = regex.exec(fileContent))) {
      mywpSharedAllIndices.push(result.index);
    }
    report.mywpSharedAll.count += mywpSharedAllIndices.length;
    report.mywpSharedAll.indices = [...report.mywpSharedAll.indices, ...generateIndicesContent(mywpSharedAllIndices, file, fileContent)];
  });


  // CHECKING STYLES FILE CONTENT
  // ----------------------------

  const scssFiles = glob.sync('**/*.scss', { cwd: srcPath, nodir: true, follow: true, dot: true });
  const cssFiles = glob.sync('**/*.css', { cwd: srcPath, nodir: true, follow: true, dot: true });

  let tsFiles = [];
  if (report.tsNotSoC.styleCount > 0) {
    tsFiles = glob.sync('**/*.ts', { cwd: srcPath, nodir: true, follow: true, dot: true });
  }

  files = [...scssFiles, ...cssFiles, ...tsFiles];

  report.scssFilesCount += [...scssFiles, ...cssFiles].length;

  files.forEach((file) => {
    const filePath = path.join(srcPath, file);
    const fileContent = tools.getFileContent(filePath).trim();
    const linesCount = fileContent.split('\n').length;

    if (fileContent.indexOf('styles-audit-disabled') !== -1) {
      report.stylesAuditDisabledCount++;
      return;
    }

    if (fileContent === '') {
      report.scssEmptyFiles++;
    }
    if (file.indexOf('.scss') > -1 || file.indexOf('.css') > -1) {
      report.scssLinescount += linesCount;
    }

    let result, regex;

    if (file.indexOf('.scss') > -1 || file.indexOf('.css') > -1) {
      let euiIndices = [];
      regex = /\.eui|\.ux/gi;
      while ((result = regex.exec(fileContent))) {
        euiIndices.push(result.index);
      }
      report.euiOverrides.count += euiIndices.length;
      report.euiOverrides.indices = [...report.euiOverrides.indices, ...generateIndicesContent(euiIndices, file, fileContent)];
    }

    let sizesIndices = [];
    regex = /px |px;/gi;
    while ((result = regex.exec(fileContent))) {
      sizesIndices.push(result.index);
    }
    report.sizesPxEm.count += sizesIndices.length;
    report.sizesPxEm.indices = [...report.sizesPxEm.indices, ...generateIndicesContent(sizesIndices, file, fileContent)];

    let boxShadowIndices = [];
    regex = /box-shadow/gi;
    while ((result = regex.exec(fileContent))) {
      boxShadowIndices.push(result.index);
    }
    report.boxShadow.count += boxShadowIndices.length;
    report.boxShadow.indices = [...report.boxShadow.indices, ...generateIndicesContent(boxShadowIndices, file, fileContent)];

    let fontFamilyIndices = [];
    regex = /font-family/gi;
    while ((result = regex.exec(fileContent))) {
      fontFamilyIndices.push(result.index);
    }
    report.fontFamily.count += fontFamilyIndices.length;
    report.fontFamily.indices = [...report.fontFamily.indices, ...generateIndicesContent(fontFamilyIndices, file, fileContent)];

    let importantIndices = [];
    regex = /!important/gi;
    while ((result = regex.exec(fileContent))) {
      importantIndices.push(result.index);
    }
    report.important.count += importantIndices.length;
    report.important.indices = [...report.important.indices, ...generateIndicesContent(importantIndices, file, fileContent)];

    let colorsIndices = [];
    regex = /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|rgba|hsl/gi;
    while ((result = regex.exec(fileContent))) {
      colorsIndices.push(result.index);
    }
    report.plainColors.count += colorsIndices.length;
    report.plainColors.indices = [...report.plainColors.indices, ...generateIndicesContent(colorsIndices, file, fileContent)];

    let ngDeepIndices = [];
    regex = /::ng-deep/gi;
    while ((result = regex.exec(fileContent))) {
      ngDeepIndices.push(result.index);
    }
    report.ngDeep.count += ngDeepIndices.length;
    report.ngDeep.indices = [...report.ngDeep.indices, ...generateIndicesContent(ngDeepIndices, file, fileContent)];

    let zIndexIndices = [];
    regex = /z-index/gi;
    while ((result = regex.exec(fileContent))) {
      zIndexIndices.push(result.index);
    }
    report.zIndex.count += zIndexIndices.length;
    report.zIndex.indices = [...report.zIndex.indices, ...generateIndicesContent(zIndexIndices, file, fileContent)];
  });


  // CHECKING HTML FILES CONTENT
  // ---------------------------

  const htmlFiles = glob.sync('**/*.html', { cwd: srcPath, nodir: true, follow: true, dot: true });

  tsFiles = [];
  if (report.tsNotSoC.templateCount.length > 0) {
    tsFiles = glob.sync('**/*.ts', { cwd: srcPath, nodir: true, follow: true, dot: true });
  }

  files = [...htmlFiles, ...tsFiles];

  report.htmlFilesCount += htmlFiles.length;

  files.forEach((file) => {
    const filePath = path.join(srcPath, file);
    const fileContent = tools.getFileContent(filePath);
    const linesCount = fileContent.split('\n').length;

    if (fileContent.indexOf('styles-audit-disabled') !== -1) {
      report.stylesAuditDisabledCount++;
      return;
    }

    if (file.indexOf('.html') > -1) {
      report.htmlLinesCount += linesCount;
    }

    let result,
      inlineStylesIndices = [];
    let regex = /style=|style =/gi;
    while ((result = regex.exec(fileContent))) {
      inlineStylesIndices.push(result.index);
    }
    report.inlineStyles.count += inlineStylesIndices.length;
    report.inlineStyles.indices = [...report.inlineStyles.indices, ...generateIndicesContent(inlineStylesIndices, file, fileContent)];

    let uxCmpIndices = [];
    regex = /<ux-/gi;
    while ((result = regex.exec(fileContent))) {
      uxCmpIndices.push(result.index);
    }
    const indicesContent = generateIndicesContent(uxCmpIndices, file, fileContent);

    report.uxCmp.count += recalculateIndicesCount(indicesContent);
    report.uxCmp.indices = [...report.uxCmp.indices, ...indicesContent];
  });



  // Analyzing 3rd party dependencies usage
  if (!pkg.standalone) {
    tools.logInfo('Analyzing package deps for 3rd parties usage');
    let deps = installUtils.packages.getLocalPackageDepsAll(pkg);
    tools.logInfo('Deps found for package :');
    deps = Object.keys(deps);
    console.log(deps);

    const allowedScopes = configUtils.packages.getPackageScopes();
    const exclusions = ['ag-grid', 'file-saver'];

    let thirdPartyDeps = [];
    deps.forEach((d) => {
      const scope = d.split('/')[0];

      // checking against allowed CSDR known package scopes
      if (!allowedScopes.includes(scope)) {
        // exclusions known
        let exclusionFound = false;
        exclusions.forEach((exc) => {
          if (scope.indexOf(exc) > -1) {
            exclusionFound = true;
          }
        });

        if (!exclusionFound) {
          thirdPartyDeps.push(d);
        }
      }
    });

    tools.logInfo('3rd party deps found for package :');
    console.log(thirdPartyDeps);

    report.thirdPartyDependencies.count = thirdPartyDeps.length;
    report.thirdPartyDependencies.dependencies = thirdPartyDeps;
  }

  // GLOBAL STATS - ANALYZING DATA / SET STATUS

  if (report.htmlFilesCount !== 0) {
    const scssHtmlRatio = Math.floor((100 * report.scssFilesCount) / report.htmlFilesCount);
    report.finalReport['scssHtmlRatio'] = {
      description: 'scss/css files VS html files',
      value: `${report.scssFilesCount} out of ${report.htmlFilesCount} (${scssHtmlRatio}%)`,
      status: scssHtmlRatio >= 25 ? 'CRITICAL' : scssHtmlRatio >= 10 && scssHtmlRatio <= 25 ? 'IMPROVE' : 'OK',
      comment: null,
    };
    if (report.finalReport['scssHtmlRatio'].status === 'CRITICAL') {
      report.finalReport['scssHtmlRatio'].comment = 'The percentage of html files having styles declaration is too high';
    }
  }

  if (report.htmlLinesCount !== 0) {
    const scssHtmlLinesRatio = Math.floor((100 * report.scssLinescount) / report.htmlLinesCount);
    report.finalReport['scssHtmlLinesRatio'] = {
      description: 'css lines count VS html lines count',
      value: `${report.scssLinescount} / ${report.htmlLinesCount} (${scssHtmlLinesRatio}%)`,
      status: scssHtmlLinesRatio >= 25 ? 'CRITICAL' : scssHtmlLinesRatio >= 10 && scssHtmlLinesRatio <= 25 ? 'IMPROVE' : 'OK',
      comment: null,
    };
    if (report.finalReport['scssHtmlLinesRatio'].status === 'CRITICAL') {
      report.finalReport['scssHtmlLinesRatio'].comment = 'The percentage of scss lines is too high';
    }
  }

  if (report.scssFilesCount !== 0) {
    report.finalReport['scssEmptyFiles'] = {
      description: 'scss/css empty files',
      value: `${report.scssEmptyFiles} out of ${report.scssFilesCount} (${Math.floor(
        (100 * report.scssEmptyFiles) / report.scssFilesCount
      )}%)`,
      status: report.scssEmptyFiles !== 0 ? 'IMPROVE' : 'OK',
      comment: report.scssEmptyFiles !== 0 ? 'Scss files without content should be cleaned up' : null,
    };
  }

  if (report.stylesAuditDisabledCount !== 0) {
    report.finalReport['stylesAuditDisabledCount'] = {
      description: 'audit disabled count',
      value: report.stylesAuditDisabledCount,
      status: report.stylesAuditDisabledCount !== 0 ? 'IMPROVE' : 'OK',
      comment: report.stylesAuditDisabledCount !== 0 ? 'If not done yet, files to be checked by eUI team' : null,
    };
  }

  // BALANCED - styles content

  if (report.scssFilesCount !== 0 || report.tsNotSoC.styleCount !== 0) {
    report.finalReport['euiOverrides'] = {
      description: 'eUI overrides found',
      value: report.euiOverrides.count,
      status: getStatus(report.euiOverrides.count),
      comment: report.euiOverrides.count !== 0 ? 'No eUI overrides should be applied, contact eUI support for assistance' : null,
    };
    report.finalReport['sizesPxEm'] = {
      description: 'Sizes in px usage found',
      value: report.sizesPxEm.count,
      status: getStatus(report.sizesPxEm.count),
      comment: report.sizesPxEm.count !== 0 ? 'if sizes should be tweaked, usage of eUI CSS vars should be applied' : null,
    };
    report.finalReport['boxShadow'] = {
      description: 'box-shadow usage found',
      value: report.boxShadow.count,
      status: getStatus(report.boxShadow.count),
      comment:
        report.boxShadow.count !== 0
          ? 'if box-shadow should be tweaked (on specific context), usage of eUI CSS vars should be applied'
          : null,
    };
    report.finalReport['fontFamily'] = {
      description: 'font-family usage found',
      value: report.fontFamily.count,
      status: getStatus(report.fontFamily.count),
      comment:
        report.fontFamily.count !== 0
          ? 'if font-family should be tweaked (on specific context), usage of eUI CSS vars should be applied'
          : null,
    };
    report.finalReport['plainColors'] = {
      description: 'Plain colors usage found',
      value: report.plainColors.count,
      status: getStatus(report.plainColors.count),
      comment: report.plainColors.count !== 0 ? 'if colors should be used in scss, usage of eUI CSS vars should be applied' : null,
    };
    report.finalReport['important'] = {
      description: '!important usage found',
      value: report.important.count,
      status: getStatus(report.important.count),
      comment: report.important.count !== 0 ? 'No !important allowed' : null,
    };
    report.finalReport['ngDeep'] = {
      description: '::ng-deep usage found',
      value: report.ngDeep.count,
      status: getStatus(report.ngDeep.count),
      comment: report.ngDeep.count !== 0 ? 'Avoid ::ng-deep usage' : null,
    };
    report.finalReport['zIndex'] = {
      description: 'z-index usage found',
      value: report.zIndex.count,
      status: getStatus(report.zIndex.count),
      comment: report.zIndex.count !== 0 ? 'Avoid z-index setting, usage of eUI CSS vars should be applied' : null,
    };
  }

  // CRITICAL ONLY

  if (report.htmlLinesCount !== 0 || report.tsNotSoC.templateCount !== 0) {
    report.finalReport['inlineStyles'] = {
      description: 'inline styles found in HTML',
      value: report.inlineStyles.count,
      status: report.inlineStyles.count !== 0 ? 'CRITICAL' : 'OK',
      comment:
        report.inlineStyles.count !== 0
          ? 'No inline styles should be present in html, usage classes with scss / eUI utilities instead'
          : null,
    };
    report.finalReport['material'] = {
      description: 'material component usage found in HTML',
      value: report.material.count,
      status: report.material.count !== 0 ? 'CRITICAL' : 'OK',
      comment: report.material.count !== 0 ? 'Usage of material should be avoided - this will be blocking as of eUI 16' : null,
    };
    report.finalReport['primeng'] = {
      description: 'PrimeNG components usage found in HTML',
      value: report.primeng.count,
      status: report.primeng.count !== 0 ? 'CRITICAL' : 'OK',
      comment: report.primeng.count !== 0 ? 'Remove any PrimeNG usage, deprecated in eUI - this will be blocking as of eUI 16' : null,
    };
    report.finalReport['allModules'] = {
      description: 'Usage of EuiAllModule or UxAllModule',
      value: report.allModules.count,
      status: report.allModules.count !== 0 ? 'CRITICAL' : 'OK',
      comment: report.allModules.count !== 0 ? 'Use only tree-shakable eUI module imports (as of 15+)' : null,
    };
    report.finalReport['mywpSharedAll'] = {
      description: 'Usage of @mywp/shared import without sub-entry',
      value: report.mywpSharedAll.count,
      status: report.mywpSharedAll.count !== 0 ? 'CRITICAL' : 'OK',
      comment: report.mywpSharedAll.count !== 0 ? 'use only import of @mywp/shared/SUB_ENTRY (as of 16+)' : null,
    };

    // IMPROVE ONLY

    report.finalReport['uxCmp'] = {
      description: 'eUI ux- components usage found in HTML',
      value: report.uxCmp.count,
      status: report.uxCmp.count !== 0 ? 'IMPROVE' : 'OK',
      comment: report.uxCmp.count !== 0 ? 'Replace by "eui-" components whenever possible, to ensure future proof migration' : null,
    };

    report.finalReport['tsOver500'] = {
      description: 'TS file containing more than 500 lines',
      value: report.tsOver500.count,
      status: report.tsOver500.count !== 0 ? 'IMPROVE' : 'OK',
      comment: report.tsOver500.count !== 0 ? 'Split TS files into multiple ones for readability' : null,
    };

    report.finalReport['tsNotSoC'] = {
      description: 'TS file not respecting SoC template OR scss split content',
      value: report.tsNotSoC.count,
      status: report.tsNotSoC.count !== 0 ? 'IMPROVE' : 'OK',
      comment: report.tsNotSoC.count !== 0 ? 'Split TS file into types of concerns' : null,
    };
  }

  report.finalReport['thirdPartyDependencies'] = {
    description: 'Third party dependencies usage',
    value: report.thirdPartyDependencies.count,
    status: report.thirdPartyDependencies.count !== 0 ? 'IMPROVE' : 'OK',
    comment:
      report.thirdPartyDependencies.count !== 0
        ? 'Use 3rd party dependencies only if really necessary (bundle size increase) - contact eUI team for more info'
        : null,
  };

  if (Object.keys(report.finalReport).length === 0) {
    tools.logInfo('No sources to audit...skipping');
    return null;
  } else {
    // Calculating score

    let score = 0,
      total = 0;

    Object.entries(report.finalReport).forEach((v) => {
      total++;

      switch (v[1].status) {
        case 'OK':
          score++;
          break;
        case 'IMPROVE':
          score += 0.5;
          break;
      }
    });

    report.score = score;
    report.total = total;
    report.pcScore = Math.floor((100 * score) / total);

    // return JSON report

    tools.logInfo('STATS report');
    console.log(JSON.stringify(report, null, 2));

    return report;
  }
});

module.exports.audit = (pkg) => {
  if (pkg.remote && pkg.name.indexOf('-ui') === -1) {
    return;
  }

  let outputReport;

  tools.logTitle('Audit package styles');

  const report = runStylesAudit(pkg);

  if (!report) {
    return;
  }

  outputReport = report;

  return Promise.resolve()
    .then(() => {
      // FINAL REPORT

      let finalReportMessage = `*STYLES AUDIT REPORT for ${pkg.name}:*\n\n`;

      Object.entries(report.finalReport).forEach((v) => {
        let statusEmoji;

        if (v[1].status === 'CRITICAL') {
          statusEmoji = ':no_entry:';
        } else if (v[1].status === 'IMPROVE') {
          statusEmoji = ':warning:';
        } else {
          statusEmoji = ':large_green_circle:';
        }

        finalReportMessage += `${statusEmoji} *${v[1].description}*: found *${v[1].value}* - status: *${v[1].status}* ${
          v[1].comment ? '==> ' + v[1].comment : ''
        }\n`;
      });

      finalReportMessage += `\neUI compliance score : *${report.score}* out of *${report.total}* *(${report.pcScore}%)*`;

      tools.logInfo('Sending final report message');
      console.log(finalReportMessage);

      return notificationUtils.package.sendPackageMessage({
        package: pkg,
        text: finalReportMessage,
      });
    })

    .then(() => {
      let configOptions, euiVersion;

      // getting config options for gates defined and euiVersion
      if (pkg.standalone) {
        configOptions = configUtils.global.getConfigOptionsStandalone();
        euiVersion = configUtils.packages.getPackageEuiVersion(pkg);

      } else {
        configOptions = configUtils.global.getConfigOptions();
        euiVersion = configUtils.global.getLocalEuiVersion();
      }

      // if eUI version not found, no action
      if (!euiVersion) {
        return;
      }

      tools.logTitle(`Checking audit styles gates`);

      // getting gates
      let gates;
      if (!configOptions.AUDIT_STYLES_GATES) {
        return;
      }

      const euiVersionGates = configOptions.AUDIT_STYLES_GATES[euiVersion];
      const allNewGates = configOptions.AUDIT_STYLES_GATES['ALL_NEW'];

      tools.logInfo('Checking if the package as gates forced');
      if (pkg.build && pkg.build.stylesAuditCheck) {
        tools.logInfo('All gates checks applied');
        gates = allNewGates;
      } else {
        tools.logInfo('===> no forced gates flag detected ...');
        // tools.logInfo('Checking if package is newly created -- all versions gates are checked in that case');

        // if (metadataUtils.packageUtils.isNewPackageBuild(pkg)) {
        //   gates = allNewGates;
        // } else {
          if (euiVersionGates) {
            tools.logInfo('eUI version gates found, applied to older packages where limited gates are set');
            gates = euiVersionGates;
          } else {
            tools.logInfo('No gates found for local eUI version...');
            return;
          }
        // }
      }

      tools.logInfo(`Gates found : ${JSON.stringify(gates)}`);

      // checking gates level if any
      let gatesPassed = true;

      Object.keys(report.finalReport).forEach((styleCategory) => {
        tools.logInfo(`Checking audit styles category : ${styleCategory} - item found ${report.finalReport[styleCategory].value}`);

        if (gates[styleCategory] === undefined) {
          tools.logInfo(`No gates found for category`);
          tools.logInfo(`===> PASSED`);
        } else {
          tools.logInfo(`Gates found for category maxium allowed : ${gates[styleCategory]}`);
          if (report.finalReport[styleCategory].value > gates[styleCategory]) {
            tools.logError(`===> FAILED`);
            gatesPassed = false;
          } else {
            tools.logInfo(`===> PASSED`);
          }
        }
      });

      if (!gatesPassed) {
        throw new Error('AUDIT_STYLES_GATES_FAILED');
      }
    })

    .then(() => {
      // formatting report for metadata storage

      const metadataReport = {
        score: outputReport.score,
        total: outputReport.total,
        pcScore: outputReport.pcScore,
      };

      const summarizedFinalReport = {};
      Object.keys(outputReport.finalReport).forEach((item) => {
        summarizedFinalReport[item] = {
          value: outputReport.finalReport[item].value,
          status: outputReport.finalReport[item].status,
        };
      });

      metadataReport.finalReport = summarizedFinalReport;

      return metadataReport;
    })

    .catch((e) => {
      throw e;
    });
};
