"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var lodash = require("lodash");
var ts = require("typescript");
var benchmark_1 = require("../shared/benchmark");
var project_1 = require("../shared/project");
var Compiler = /** @class */ (function () {
    function Compiler(config, log, project) {
        var _this = this;
        this.config = config;
        this.log = log;
        this.project = project;
        this.compiledFiles = {};
        this.emitQueue = [];
        this.errors = [];
        this.getSourceFile = function (filename, languageVersion, onError) {
            if (_this.cachedProgram && !_this.isQueued(filename)) {
                var sourceFile = _this.cachedProgram.getSourceFile(filename);
                if (sourceFile) {
                    return sourceFile;
                }
            }
            return _this.hostGetSourceFile(filename, languageVersion, onError);
        };
        config.whenReady(function () {
            _this.log.debug("Setting up deferred project compilation");
            _this.compileDeferred = lodash.debounce(function () {
                _this.compileProject();
            }, _this.config.compilerDelay);
        });
    }
    Compiler.prototype.compile = function (file, callback) {
        this.emitQueue.push({
            callback: callback,
            file: file
        });
        this.compileDeferred();
    };
    Compiler.prototype.compileProject = function () {
        this.log.info("Compiling project using Typescript %s", ts.version);
        if (this.project.handleFileEvent() === project_1.EventType.FileSystemChanged) {
            this.setupRecompile();
        }
        var benchmark = new benchmark_1.Benchmark();
        var tsconfig = this.project.getTsconfig();
        this.outputDiagnostics(tsconfig.errors);
        if (+ts.version[0] >= 3) {
            this.program = ts.createProgram({
                host: this.compilerHost,
                options: tsconfig.options,
                projectReferences: tsconfig.projectReferences,
                rootNames: tsconfig.fileNames
            });
        }
        else {
            this.program = ts.createProgram(tsconfig.fileNames, tsconfig.options, this.compilerHost);
        }
        this.cachedProgram = this.program;
        this.runDiagnostics(this.program, this.compilerHost);
        this.program.emit();
        this.log.info("Compiled %s files in %s ms.", tsconfig.fileNames.length, benchmark.elapsed());
        this.onProgramCompiled();
    };
    Compiler.prototype.setupRecompile = function () {
        var _this = this;
        this.cachedProgram = undefined;
        this.compilerHost = ts.createCompilerHost(this.project.getTsconfig().options);
        this.hostGetSourceFile = this.compilerHost.getSourceFile;
        this.compilerHost.getSourceFile = this.getSourceFile;
        this.compilerHost.writeFile = function (filename, text) {
            _this.compiledFiles[filename] = text;
        };
    };
    Compiler.prototype.onProgramCompiled = function () {
        var _this = this;
        this.emitQueue.forEach(function (queued) {
            var sourceFile = _this.program.getSourceFile(queued.file.originalPath);
            if (!sourceFile) {
                throw new Error("No source found for " + queued.file.originalPath + "!\n" +
                    "Is there a mismatch between the Typescript compiler options and the Karma config?");
            }
            var ambientModuleNames = sourceFile.ambientModuleNames;
            queued.callback({
                ambientModuleNames: ambientModuleNames,
                hasError: _this.errors.indexOf(queued.file.originalPath) !== -1,
                isAmbientModule: ambientModuleNames && ambientModuleNames.length > 0,
                isDeclarationFile: _this.fileExtensionIs(sourceFile.fileName, ".d.ts"),
                outputText: _this.compiledFiles[queued.file.path],
                sourceFile: sourceFile,
                sourceMapText: _this.compiledFiles[queued.file.path + ".map"]
            });
        });
        this.emitQueue.length = 0;
    };
    Compiler.prototype.isQueued = function (filename) {
        for (var _i = 0, _a = this.emitQueue; _i < _a.length; _i++) {
            var queued = _a[_i];
            if (queued.file.originalPath === filename) {
                return true;
            }
        }
        return false;
    };
    Compiler.prototype.runDiagnostics = function (program, host) {
        this.errors = [];
        var diagnostics = ts.getPreEmitDiagnostics(program);
        this.outputDiagnostics(diagnostics, host);
    };
    Compiler.prototype.outputDiagnostics = function (diagnostics, host) {
        var _this = this;
        if (!diagnostics || diagnostics.length === 0) {
            return;
        }
        diagnostics.forEach(function (diagnostic) {
            if (diagnostic.file) {
                _this.errors.push(diagnostic.file.fileName);
            }
            if (ts.formatDiagnostics && host) { // v1.8+
                _this.log.error(ts.formatDiagnostics([diagnostic], host));
            }
            else { // v1.6, v1.7
                var output = "";
                if (diagnostic.file) {
                    var loc = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
                    output += diagnostic.file.fileName.replace(process.cwd(), "") +
                        "(" + (loc.line + 1) + "," + (loc.character + 1) + "): ";
                }
                var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase();
                output += category + " TS" + diagnostic.code + ": " +
                    ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine) + ts.sys.newLine;
                _this.log.error(output);
            }
        });
        if (this.project.getTsconfig().options.noEmitOnError) {
            ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
        }
    };
    Compiler.prototype.fileExtensionIs = function (path, extension) {
        return path.length > extension.length && this.endsWith(path, extension);
    };
    Compiler.prototype.endsWith = function (str, suffix) {
        var expectedPos = str.length - suffix.length;
        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
    };
    return Compiler;
}());
exports.Compiler = Compiler;
//# sourceMappingURL=compiler.js.map