import { defineConfig } from 'cypress';
import * as fs from 'fs';
import CypressRunResult = CypressCommandLine.CypressRunResult;
import CypressFailedRunResult = CypressCommandLine.CypressFailedRunResult;
import { TestrailUtility, Timeouts } from '@utility-lib/index';
import { readPdf, hasPDF } from 'cypress/scripts/readPdf';
import installLogsPrinter from 'cypress-terminal-report/src/installLogsPrinter';
import getCompareSnapshotsPlugin from 'cypress-visual-regression/dist/plugin';

const pdf2html = require('pdf2html');
const toHtml = async (fileName: string) => {
  return await pdf2html.html(fileName);
};
const allureWriter = require('@shelex/cypress-allure-plugin/writer');
const { verifyDownloadTasks } = require('cy-verify-downloads');
const { removeDirectory } = require('cypress-delete-downloads-folder');
const { cloudPlugin } = require('cypress-cloud/plugin');

/**
 * @type {Cypress.PluginConfig}
 */
const cache: { [key: string]: any } = { id: {} };

export default defineConfig({
  projectId: 'qe-fe-automation',
  fixturesFolder: 'cypress/fixtures',
  video: true,
  videoUploadOnPasses: false,
  chromeWebSecurity: false,
  viewportHeight: 1000,
  viewportWidth: 1440,
  defaultCommandTimeout: 30000,
  responseTimeout: 120000,
  taskTimeout: 120000,
  pageLoadTimeout: 120000,
  requestTimeout: 120000,
  numTestsKeptInMemory: 50,
  experimentalMemoryManagement: true,
  retries: { runMode: 2, openMode: 0 },
  downloadsFolder: 'cypress/downloads',
  scrollBehavior: 'center',
  env: {
    allure: true,
    allureResultsPath: 'allure-results',
    allureReuseAfterSpec: true,
    allureLogCypress: true,
    grepFilterSpecs: true,
    grepOmitFiltered: true,
    testrailRunId: process.env.RUN_ID,
    testrailDomain: process.env.TESTRAIL_DOMAIN,
    testrailUsername: process.env.TR_USER_USR,
    testrailPassword: process.env.TR_USER_PSW,
    testSupportServiceUrl: 'https://test-support-staging-prime.tripactions-staging.com',
    screenshotsFolder: './cypress/snapshots/actual',
    trashAssetsBeforeRuns: true,
    video: false,
    type: 'actual'
  },
  e2e: {
    experimentalModifyObstructiveThirdPartyCode: true,
    // We've imported your old cypress plugins here.
    // You may want to clean this up later by importing these.
    setupNodeEvents(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) {
      on('after:run', (results: CypressRunResult | CypressFailedRunResult) => {
        const res: CypressRunResult = results as CypressRunResult;
        if (results) {
          console.log(`Total Tests: ${res.totalTests}`);
          console.log(`Total passed: ${res.totalPassed}`);
          const percentage: number = (res.totalPassed / res.totalTests) * 100;
          let path = res.config.env.allureResultsPath;
          if (fs.existsSync(path)) {
            path = path + '/' + 'result.txt';
          } else {
            path = 'result.txt';
          }
          console.log(`Path: ${path}`);
          fs.writeFileSync(path, percentage.toString());
        }
      });
      allureWriter(on, config);
      on('after:spec', async (spec, results) => {
        const tests = results.tests;
        await TestrailUtility.testRailStatusReporter(tests, {
          testrailRunId: config.env.testrailRunId,
          testrailDomain: config.env.testrailDomain,
          testrailUsername: config.env.testrailUsername,
          testrailPassword: config.env.testrailPassword
        });
      });
      on('task', {
        readPdf,
        toHtml
      });
      on('task', {
        filesInDownload(folderName) {
          return fs.readdirSync(folderName);
        }
      });
      on('task', verifyDownloadTasks);
      on('task', { removeDirectory });
      on('task', {
        isExistPDF(PDFfilename) {
          return hasPDF(PDFfilename, Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
        },
        getPDFContent(PDFfilename) {
          return readPdf(PDFfilename);
        }
      });
      on('task', {
        putDataInCache: ({ key, data }) => {
          cache[key] = data;
          return null;
        },
        getDataFromCache: (key) => cache[key] || ''
      });
      require('@cypress/grep/src/plugin')(config);
      installLogsPrinter(on, {
        printLogsToConsole: 'onFail',
        printLogsToFile: 'onFail',
        specRoot: 'cypress'
      });
      cloudPlugin(on, config);
      getCompareSnapshotsPlugin(on, config);
      return config;
    },
    specPattern: './cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
    baseUrl: 'https://staging-prime.navan.com',
    experimentalOriginDependencies: true
  },
  watchForFileChanges: false
});
