"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.sendScreenshotsCount = sendScreenshotsCount;
var _path = _interopRequireDefault(require("path"));
var _https = _interopRequireDefault(require("https"));
var _shelljs = require("shelljs");
var _qs = require("qs");
var _lodash = require("lodash");
var _uuid = require("uuid");
var _types = require("../types");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const konturGitHost = 'git.skbkontur.ru';
const trackId = 232; // front_infra
const origin = 'http://localhost/';
const category = 'tests_run';
const action = 'done';
function buildPathname(label, info) {
  return `/track-event?${(0, _qs.stringify)({
    id: trackId,
    c: category,
    a: action,
    l: label,
    cv: typeof info == 'string' ? info : JSON.stringify(info),
    ts: new Date().toISOString(),
    url: origin
  })}`;
}
function sanitizeGridUrl(gridUrl) {
  const url = new URL(gridUrl);
  url.username = url.username ? '********' : '';
  url.password = url.password ? '********' : '';
  return url.toString();
}
function tryGetRepoUrl() {
  try {
    const gitRemoteOutput = (0, _shelljs.exec)('git remote -v', {
      silent: true
    });
    const [, repoUrl] = gitRemoteOutput.stdout.match(/origin\s+(.*)\s+\(fetch\)/) ?? [];
    return [repoUrl, null];
  } catch (error) {
    return [undefined, error];
  }
}
function tryGetStorybookVersion() {
  try {
    const storybookPackageOutput = (0, _shelljs.exec)(`node -e "console.log(JSON.stringify(require('storybook/package.json')))"`, {
      silent: true
    });
    const storybookPackage = JSON.parse(storybookPackageOutput);
    return [storybookPackage.version, null];
  } catch (error) {
    return [undefined, error];
  }
}
function tryGetCreeveyVersion() {
  try {
    // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-missing-require
    const creeveyPackage = require('creevey/package.json');
    return [creeveyPackage.version, null];
  } catch (error) {
    return [undefined, error];
  }
}
function sendRequest(options) {
  return new Promise((resolve, reject) => {
    const req = _https.default.request(options, res => {
      if (res.statusCode) {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve();
        } else if (res.statusCode >= 300 && res.statusCode < 400) {
          reject(new Error(`Redirection error: ${res.statusCode}`));
        } else if (res.statusCode >= 400 && res.statusCode < 500) {
          reject(new Error(`Client error: ${res.statusCode}`));
        } else if (res.statusCode >= 500 && res.statusCode < 600) {
          reject(new Error(`Server error: ${res.statusCode}`));
        } else {
          reject(new Error(`Unexpected status code: ${res.statusCode}`));
        }
      } else {
        reject(new Error('No status code received'));
      }
    });
    req.on('error', reject);
    req.end();
  });
}
async function sendScreenshotsCount(config, options, status) {
  var _config$storiesProvid;
  const [repoUrl] = tryGetRepoUrl();
  const isKonturRepo = repoUrl === null || repoUrl === void 0 ? void 0 : repoUrl.includes(konturGitHost);
  if (!isKonturRepo || config.disableTelemetry) return;
  const uuid = (0, _uuid.v4)();
  const [creeveyVersion, creeveyVersionError] = tryGetCreeveyVersion();
  const [storybookVersion, storybookVersionError] = tryGetStorybookVersion();
  const gridUrl = config.gridUrl ? sanitizeGridUrl(config.gridUrl) : undefined;
  const configMeta = {
    runId: uuid,
    repoUrl: repoUrl ?? 'unknown',
    creeveyVersion: creeveyVersion ?? 'unknown',
    storybookVersion: storybookVersion ?? 'unknown',
    options: options._,
    gridUrl,
    screenDir: config.screenDir ? _path.default.relative(process.cwd(), config.screenDir) : undefined,
    useDocker: config.useDocker,
    dockerImage: config.dockerImage,
    maxRetries: config.maxRetries,
    diffOptions: config.diffOptions,
    storiesProvider: ((_config$storiesProvid = config.storiesProvider) === null || _config$storiesProvid === void 0 ? void 0 : _config$storiesProvid.providerName) ?? 'unknown',
    errors: [creeveyVersionError, storybookVersionError].some(Boolean) ? [creeveyVersionError ? `Error while getting creevey version: ${creeveyVersionError.message}` : undefined, storybookVersionError ? `Error while getting storybook version: ${storybookVersionError.message}` : undefined].filter(Boolean) : undefined
  };
  const browsersMeta = {
    runId: uuid,
    browsers: Object.fromEntries(Object.entries(config.browsers ?? {}).map(([name, browser]) => [name, typeof browser === 'object' ? {
      name: browser.name,
      gridUrl: browser.gridUrl ? sanitizeGridUrl(browser.gridUrl) : undefined,
      browserName: browser.browserName,
      browserVersion: browser.browserVersion,
      platformName: browser.platformName,
      viewport: browser.viewport,
      limit: browser.limit,
      dockerImage: browser.dockerImage,
      'se:teamname': browser['se:teamname']
    } : browser]))
  };
  const tests = {};
  Object.values((status === null || status === void 0 ? void 0 : status.tests) ?? {}).filter(_types.isDefined).forEach(test => {
    (0, _lodash.set)(tests, [...test.storyPath, test.testName, test.browser].filter(_types.isDefined), test.id);
  });
  const testsMeta = {
    runId: uuid,
    tests
  };
  const fullPathname = buildPathname('tests', testsMeta);
  // NOTE: Keep request path shorter than 32k symbols
  const chunksCount = Math.ceil(fullPathname.length / 32_000);
  let chunks = [];
  if (chunksCount > 1) {
    const testsString = JSON.stringify(tests);
    const chunkSize = Math.ceil(testsString.length / chunksCount);
    chunks = Array.from({
      length: chunksCount
    }).map((_, chunkIndex) => testsString.slice(chunkIndex * chunkSize, (chunkIndex + 1) * chunkSize)).map((testsPart, seq) => buildPathname('tests', {
      runId: uuid,
      tests: testsPart,
      seq
    }));
  } else {
    chunks = [fullPathname];
  }
  await Promise.all([sendRequest({
    host: 'metrika.kontur.ru',
    path: buildPathname('config', configMeta),
    protocol: 'https:'
  }), sendRequest({
    host: 'metrika.kontur.ru',
    path: buildPathname('browsers', browsersMeta),
    protocol: 'https:'
  }), ...chunks.map(chunk => sendRequest({
    host: 'metrika.kontur.ru',
    path: chunk,
    protocol: 'https:'
  }))]);
}