"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.HtmlBuilder = void 0;

var _fs = _interopRequireDefault(require("fs"));

var _path = _interopRequireDefault(require("path"));

var _utils = require("../../utils/utils");

var _json = require("../reporters/json");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
class HtmlBuilder {
  constructor(rawReports, outputDir, rootDir) {
    this._reportFolder = void 0;
    this._tests = new Map();
    this._rootDir = void 0;
    this._rootDir = rootDir;
    this._reportFolder = _path.default.resolve(process.cwd(), outputDir);

    const dataFolder = _path.default.join(this._reportFolder, 'data');

    _fs.default.mkdirSync(dataFolder, {
      recursive: true
    });

    const appFolder = _path.default.join(__dirname, '..', '..', 'web', 'htmlReport2');

    for (const file of _fs.default.readdirSync(appFolder)) _fs.default.copyFileSync(_path.default.join(appFolder, file), _path.default.join(this._reportFolder, file));

    const projects = [];

    for (const projectFile of rawReports) {
      const projectJson = JSON.parse(_fs.default.readFileSync(projectFile, 'utf-8'));
      const suites = [];

      for (const file of projectJson.suites) {
        const relativeFileName = this._relativeLocation(file.location).file;

        const fileId = (0, _utils.calculateSha1)(projectFile + ':' + relativeFileName);
        const tests = [];
        suites.push(this._createSuiteTreeItem(file, fileId, tests));
        const testFile = {
          fileId,
          path: relativeFileName,
          tests: tests.map(t => this._createTestCase(t))
        };

        _fs.default.writeFileSync(_path.default.join(dataFolder, fileId + '.json'), JSON.stringify(testFile, undefined, 2));
      }

      projects.push({
        name: projectJson.project.name,
        suites,
        failedTests: suites.reduce((a, s) => a + s.failedTests, 0)
      });
    }

    _fs.default.writeFileSync(_path.default.join(dataFolder, 'projects.json'), JSON.stringify(projects, undefined, 2));
  }

  _createTestCase(test) {
    return {
      testId: test.testId,
      title: test.title,
      location: this._relativeLocation(test.location),
      results: test.results.map(r => this._createTestResult(r))
    };
  }

  _createSuiteTreeItem(suite, fileId, testCollector) {
    const suites = suite.suites.map(s => this._createSuiteTreeItem(s, fileId, testCollector));
    const tests = suite.tests.map(t => this._createTestTreeItem(t, fileId));
    testCollector.push(...suite.tests);
    return {
      title: suite.title,
      location: this._relativeLocation(suite.location),
      duration: suites.reduce((a, s) => a + s.duration, 0) + tests.reduce((a, t) => a + t.duration, 0),
      failedTests: suites.reduce((a, s) => a + s.failedTests, 0) + tests.reduce((a, t) => t.outcome === 'unexpected' || t.outcome === 'flaky' ? a + 1 : a, 0),
      suites,
      tests
    };
  }

  _createTestTreeItem(test, fileId) {
    const duration = test.results.reduce((a, r) => a + r.duration, 0);

    this._tests.set(test.testId, test);

    return {
      testId: test.testId,
      fileId: fileId,
      location: this._relativeLocation(test.location),
      title: test.title,
      duration,
      outcome: test.outcome
    };
  }

  _createTestResult(result) {
    var _result$error;

    return {
      duration: result.duration,
      startTime: result.startTime,
      retry: result.retry,
      steps: result.steps.map(s => this._createTestStep(s)),
      error: (_result$error = result.error) === null || _result$error === void 0 ? void 0 : _result$error.message,
      status: result.status
    };
  }

  _createTestStep(step) {
    var _step$error;

    return {
      title: step.title,
      startTime: step.startTime,
      duration: step.duration,
      steps: step.steps.map(s => this._createTestStep(s)),
      log: step.log,
      error: (_step$error = step.error) === null || _step$error === void 0 ? void 0 : _step$error.message
    };
  }

  _relativeLocation(location) {
    if (!location) return {
      file: '',
      line: 0,
      column: 0
    };
    return {
      file: (0, _json.toPosixPath)(_path.default.relative(this._rootDir, location.file)),
      line: location.line,
      column: location.column
    };
  }

}

exports.HtmlBuilder = HtmlBuilder;