text: "use strict";
  var fs_1 = require("fs");
  var ts = require("typescript");
  var configuration_1 = require("./configuration");
  var enableDisableRules_1 = require("./enableDisableRules");
  var formatterLoader_1 = require("./formatterLoader");
  var typedRule_1 = require("./language/rule/typedRule");
  var utils_1 = require("./language/utils");
  var ruleLoader_1 = require("./ruleLoader");
  var utils_2 = require("./utils");
  var MultiLinter = (function () {
      function MultiLinter(options, program) {
          this.options = options;
          this.program = program;
          this.failures = [];
      }
      MultiLinter.createProgram = function (configFile, projectDirectory) {
          if (projectDirectory === undefined) {
              var lastSeparator = configFile.lastIndexOf("/");
              if (lastSeparator < 0) {
                  projectDirectory = ".";
              }
              else {
                  projectDirectory = configFile.substring(0, lastSeparator + 1);
              }
          }
          var config = ts.readConfigFile(configFile, ts.sys.readFile).config;
          var parseConfigHost = {
              fileExists: fs_1.existsSync,
              readDirectory: ts.sys.readDirectory,
              useCaseSensitiveFileNames: true,
          };
          var parsed = ts.parseJsonConfigFileContent(config, parseConfigHost, projectDirectory);
          var host = ts.createCompilerHost(parsed.options, true);
          var program = ts.createProgram(parsed.fileNames, parsed.options, host);
          return program;
      };
      MultiLinter.getFileNames = function (program) {
          return program.getSourceFiles().map(function (s) { return s.fileName; }).filter(function (l) { return l.substr(-5) !== ".d.ts"; });
      };
      MultiLinter.prototype.lint = function (fileName, source, configuration) {
          if (configuration === void 0) { configuration = configuration_1.DEFAULT_CONFIG; }
          var sourceFile;
          if (this.program) {
              sourceFile = this.program.getSourceFile(fileName);
              if (sourceFile && !("resolvedModules" in sourceFile)) {
                  throw new Error("Program must be type checked before linting");
              }
          }
          else {
              sourceFile = utils_1.getSourceFile(fileName, source);
          }
          if (sourceFile === undefined) {
              throw new Error("Invalid source file: " + fileName + ". Ensure that the files supplied to lint have a .ts or .tsx extension.");
          }
          var rulesWalker = new enableDisableRules_1.EnableDisableRulesWalker(sourceFile, {
              disabledIntervals: [],
              ruleName: "",
          });
          rulesWalker.walk(sourceFile);
          var enableDisableRuleMap = rulesWalker.enableDisableRuleMap;
          var rulesDirectories = utils_2.arrayify(this.options.rulesDirectory)
              .concat(utils_2.arrayify(configuration.rulesDirectory));
          var configurationRules = configuration.rules;
          var configuredRules = ruleLoader_1.loadRules(configurationRules, enableDisableRuleMap, rulesDirectories);
          var enabledRules = configuredRules.filter(function (r) { return r.isEnabled(); });
          for (var _i = 0, enabledRules_1 = enabledRules; _i < enabledRules_1.length; _i++) {
              var rule = enabledRules_1[_i];
              var ruleFailures = [];
              if (this.program && rule instanceof typedRule_1.TypedRule) {
                  ruleFailures = rule.applyWithProgram(sourceFile, this.program);
              }
              else {
                  ruleFailures = rule.apply(sourceFile);
              }
              for (var _a = 0, ruleFailures_1 = ruleFailures; _a < ruleFailures_1.length; _a++) {
                  var ruleFailure = ruleFailures_1[_a];
                  if (!this.containsRule(this.failures, ruleFailure)) {
                      this.failures.push(ruleFailure);
                  }
              }
          }
      };
      MultiLinter.prototype.getResult = function () {
          var formatter;
          var formattersDirectory = configuration_1.getRelativePath(this.options.formattersDirectory);
          var formatterName = this.options.formatter || "prose";
          var Formatter = formatterLoader_1.findFormatter(formatterName, formattersDirectory);
          if (Formatter) {
              formatter = new Formatter();
          }
          else {
              throw new Error("formatter '" + formatterName + "' not found");
          }
          var output = formatter.format(this.failures);
          return {
              failureCount: this.failures.length,
              failures: this.failures,
              format: formatterName,
              output: output,
          };
      };
      MultiLinter.prototype.containsRule = function (rules, rule) {
          return rules.some(function (r) { return r.equals(rule); });
      };
      MultiLinter.VERSION = "4.0.0-dev.0";
      MultiLinter.findConfiguration = configuration_1.findConfiguration;
      MultiLinter.findConfigurationPath = configuration_1.findConfigurationPath;
      MultiLinter.getRulesDirectories = configuration_1.getRulesDirectories;
      MultiLinter.loadConfigurationFromPath = configuration_1.loadConfigurationFromPath;
      return MultiLinter;
  }());
  module.exports = MultiLinter;
  