"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const vscode_languageserver_1 = require("vscode-languageserver");
const validationProvider_1 = require("../../src/providers/validationProvider");
const helper_1 = require("../helper");
function testValidationFromCache(validationManager, textDoc) {
    it("should provide no diagnostics", async function () {
        const actualDiagnostics = await (0, validationProvider_1.doValidate)(textDoc, validationManager);
        (0, chai_1.expect)(actualDiagnostics.size).to.equal(0);
    });
}
function assertValidateTests(tests, context, validationManager, textDoc, validationEnabled) {
    tests.forEach((test) => {
        it(`should provide diagnostics for ${test.name}`, async function () {
            (0, chai_1.expect)(context).is.not.undefined;
            const actualDiagnostics = await (0, validationProvider_1.doValidate)(textDoc, validationManager, false, context);
            if (!validationEnabled) {
                (0, chai_1.expect)(actualDiagnostics.has(`file://${textDoc.uri}`)).to.be.false;
                return;
            }
            if (test.diagnosticReport.length === 0) {
                (0, chai_1.expect)(actualDiagnostics.has(`file://${textDoc.uri}`)).to.be.false;
            }
            else {
                const diags = actualDiagnostics.get(`file://${textDoc.uri}`);
                if (diags) {
                    (0, chai_1.expect)(diags.length).to.equal(test.diagnosticReport.length);
                    diags.forEach((diag, i) => {
                        const actDiag = diag;
                        const expDiag = test.diagnosticReport[i];
                        (0, chai_1.expect)(actDiag.message).include(expDiag.message);
                        (0, chai_1.expect)(actDiag.range).to.deep.equal(expDiag.range);
                        (0, chai_1.expect)(actDiag.severity).to.equal(expDiag.severity);
                        (0, chai_1.expect)(actDiag.source).to.equal(expDiag.source);
                    });
                }
                else {
                    (0, chai_1.expect)(false);
                }
            }
        });
    });
}
function testAnsibleLintErrors(context, validationManager, textDoc, validationEnabled) {
    const tests = [
        {
            name: "specific ansible lint errors and warnings (Warnings come from warn_list in ansible-lint config)",
            diagnosticReport: [
                {
                    severity: 1,
                    message: "Variables names",
                    range: {
                        start: { line: 4, character: 0 },
                        end: {
                            line: 4,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 1,
                    message: "All tasks should be named",
                    range: {
                        start: { line: 6, character: 0 },
                        end: {
                            line: 6,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 1,
                    message: "Unsupported parameters",
                    range: {
                        start: { line: 14, character: 0 },
                        end: {
                            line: 14,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 1,
                    message: "Use FQCN for builtin module actions",
                    range: {
                        start: { line: 14, character: 0 },
                        end: {
                            line: 14,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 1,
                    message: "Commands should not change things if nothing needs doing",
                    range: {
                        start: { line: 14, character: 0 },
                        end: {
                            line: 14,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 2,
                    message: "Avoid using free-form",
                    range: {
                        start: { line: 14, character: 0 },
                        end: {
                            line: 14,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
                {
                    severity: 2,
                    message: "should not use a relative path",
                    range: {
                        start: { line: 17, character: 0 },
                        end: {
                            line: 17,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "ansible-lint",
                },
            ],
        },
    ];
    assertValidateTests(tests, context, validationManager, textDoc, validationEnabled);
}
function testAnsibleSyntaxCheckNoErrors(context, validationManager, textDoc, validationEnabled) {
    const tests = [
        {
            name: "no specific ansible lint errors",
            diagnosticReport: [],
        },
    ];
    (0, chai_1.expect)(context).to.not.be.undefined;
    if (context) {
        assertValidateTests(tests, context, validationManager, textDoc, validationEnabled);
    }
}
function testAnsibleSyntaxCheckEmptyPlaybook(context, validationManager, textDoc, validationEnabled) {
    const tests = [
        {
            name: "empty playbook",
            diagnosticReport: [],
        },
    ];
    assertValidateTests(tests, context, validationManager, textDoc, validationEnabled);
}
function testAnsibleSyntaxCheckNoHost(context, validationManager, textDoc, validationEnabled) {
    const tests = [
        {
            name: "no host",
            diagnosticReport: [
                {
                    severity: 1,
                    message: "the field 'hosts' is required but was not set",
                    range: {
                        start: { line: 0, character: 0 },
                        end: {
                            line: 0,
                            character: vscode_languageserver_1.integer.MAX_VALUE,
                        },
                    },
                    source: "Ansible",
                },
            ],
        },
    ];
    assertValidateTests(tests, context, validationManager, textDoc, validationEnabled);
}
function testInvalidYamlFile(textDoc) {
    const tests = [
        {
            name: "invalid YAML",
            file: "diagnostics/invalid_yaml.yml",
            diagnosticReport: [
                {
                    severity: 1,
                    message: "Nested mappings are not allowed",
                    range: {
                        start: { line: 6, character: 13 },
                        end: {
                            line: 6,
                            character: 14,
                        },
                    },
                    source: "Ansible [YAML]",
                },
                {
                    severity: 1,
                    message: "Unexpected scalar at node end",
                    range: {
                        start: { line: 7, character: 0 },
                        end: {
                            line: 7,
                            character: 6,
                        },
                    },
                    source: "Ansible [YAML]",
                },
                {
                    severity: 1,
                    message: "Unexpected map-value-ind",
                    range: {
                        start: { line: 7, character: 6 },
                        end: {
                            line: 7,
                            character: 7,
                        },
                    },
                    source: "Ansible [YAML]",
                },
                {
                    severity: 1,
                    message: "Unexpected scalar token in YAML stream",
                    range: {
                        start: { line: 7, character: 8 },
                        end: {
                            line: 7,
                            character: 12,
                        },
                    },
                    source: "Ansible [YAML]",
                },
            ],
        },
    ];
    tests.forEach(({ name, diagnosticReport }) => {
        it(`should provide diagnostic for ${name}`, async function () {
            const actualDiagnostics = (0, validationProvider_1.getYamlValidation)(textDoc);
            (0, chai_1.expect)(actualDiagnostics.length).to.equal(diagnosticReport.length);
            actualDiagnostics.forEach((diag, i) => {
                const actDiag = diag;
                const expDiag = diagnosticReport[i];
                (0, chai_1.expect)(actDiag.message).include(expDiag.message);
                (0, chai_1.expect)(actDiag.range).to.deep.equal(expDiag.range);
                (0, chai_1.expect)(actDiag.severity).to.equal(expDiag.severity);
                (0, chai_1.expect)(actDiag.source).to.equal(expDiag.source);
            });
        });
    });
}
describe("doValidate()", () => {
    const workspaceManager = (0, helper_1.createTestWorkspaceManager)();
    const validationManager = (0, helper_1.createTestValidationManager)();
    let fixtureFilePath = "diagnostics/lint_errors.yml";
    let fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
    let context = workspaceManager.getContext(fixtureFileUri);
    let textDoc = (0, helper_1.getDoc)(fixtureFilePath);
    if (context) {
        let docSettings = context.documentSettings.get(textDoc.uri);
        describe("Get validation only from cache", () => {
            describe("With EE enabled @ee", () => {
                before(async () => {
                    (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                    await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                });
                testValidationFromCache(validationManager, textDoc);
                after(async () => {
                    (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                    await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                });
            });
            describe("With EE disabled", () => {
                before(async () => {
                    (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                    await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                });
                testValidationFromCache(validationManager, textDoc);
            });
        });
        describe("Ansible diagnostics", () => {
            describe("Diagnostics using ansible-lint", () => {
                describe("With EE enabled @ee", () => {
                    before(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                        await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                    });
                    if (context) {
                        testAnsibleLintErrors(context, validationManager, textDoc, true);
                    }
                    after(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                });
                describe("With EE disabled", () => {
                    before(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                    testAnsibleLintErrors(context, validationManager, textDoc, true);
                });
            });
            describe("Diagnostics using ansible-playbook --syntax-check", () => {
                describe("no specific ansible lint errors", () => {
                    describe("With EE enabled @ee", () => {
                        before(async () => {
                            (await docSettings).validation.lint.enabled = false;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                            await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                        });
                        testAnsibleSyntaxCheckNoErrors(context, validationManager, textDoc, true);
                        after(async () => {
                            (await docSettings).validation.lint.enabled = true;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                    });
                    describe("With EE disabled", () => {
                        before(async () => {
                            (await docSettings).validation.lint.enabled = false;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                        testAnsibleSyntaxCheckNoErrors(context, validationManager, textDoc, true);
                    });
                    after(async () => {
                        (await docSettings).validation.lint.enabled = true;
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                });
                describe("empty playbook", () => {
                    fixtureFilePath = "diagnostics/empty.yml";
                    fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
                    context = workspaceManager.getContext(fixtureFileUri);
                    textDoc = (0, helper_1.getDoc)(fixtureFilePath);
                    (0, chai_1.expect)(context).is.not.undefined;
                    if (context) {
                        docSettings = context.documentSettings.get(textDoc.uri);
                        describe("With EE enabled @ee", () => {
                            before(async () => {
                                (await docSettings).validation.lint.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                                await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckEmptyPlaybook(context, validationManager, textDoc, true);
                            after(async () => {
                                (await docSettings).validation.lint.enabled = true;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                        });
                        describe("With EE disabled", () => {
                            before(async () => {
                                (await docSettings).validation.lint.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckEmptyPlaybook(context, validationManager, textDoc, true);
                        });
                        after(async () => {
                            (await docSettings).validation.lint.enabled = true;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                    }
                });
                describe("no host", () => {
                    fixtureFilePath = "diagnostics/noHost.yml";
                    fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
                    context = workspaceManager.getContext(fixtureFileUri);
                    textDoc = (0, helper_1.getDoc)(fixtureFilePath);
                    if (context) {
                        docSettings = context.documentSettings.get(textDoc.uri);
                    }
                    describe("With EE enabled @ee", () => {
                        before(async () => {
                            (await docSettings).validation.lint.enabled = false;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                            await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                        });
                        testAnsibleSyntaxCheckNoHost(context, validationManager, textDoc, true);
                        after(async () => {
                            (await docSettings).validation.lint.enabled = true;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                    });
                    describe("With EE disabled", () => {
                        before(async () => {
                            (await docSettings).validation.lint.enabled = false;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                        testAnsibleSyntaxCheckNoHost(context, validationManager, textDoc, true);
                    });
                    after(async () => {
                        (await docSettings).validation.lint.enabled = true;
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                });
            });
            describe("Diagnostics when validation is disabled", () => {
                describe("no specific ansible lint errors", () => {
                    fixtureFilePath = "diagnostics/lint_errors.yml";
                    fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
                    context = workspaceManager.getContext(fixtureFileUri);
                    textDoc = (0, helper_1.getDoc)(fixtureFilePath);
                    (0, chai_1.expect)(context).is.not.undefined;
                    if (context) {
                        docSettings = context.documentSettings.get(textDoc.uri);
                        describe("With EE enabled @ee", () => {
                            before(async () => {
                                // (await docSettings).validation.lint.enabled = false;
                                // (await docSettings).validation.lint.path =
                                //   "invalid-ansible-lint-path";
                                (await docSettings).validation.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                                await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckNoErrors(context, validationManager, textDoc, false);
                            after(async () => {
                                // (await docSettings).validation.lint.enabled = true;
                                // (await docSettings).validation.lint.path = "ansible-lint";
                                (await docSettings).validation.enabled = true;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                        });
                        describe("With EE disabled", () => {
                            before(async () => {
                                // (await docSettings).validation.lint.enabled = false;
                                // (await docSettings).validation.lint.path =
                                // "invalid-ansible-lint-path";
                                (await docSettings).validation.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckNoErrors(context, validationManager, textDoc, false);
                        });
                        after(async () => {
                            // (await docSettings).validation.lint.enabled = true;
                            // (await docSettings).validation.lint.path = "ansible-lint";
                            (await docSettings).validation.enabled = true;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                    }
                });
                describe("no host", () => {
                    fixtureFilePath = "diagnostics/noHost.yml";
                    fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
                    context = workspaceManager.getContext(fixtureFileUri);
                    textDoc = (0, helper_1.getDoc)(fixtureFilePath);
                    (0, chai_1.expect)(context).is.not.undefined;
                    if (context) {
                        docSettings = context.documentSettings.get(textDoc.uri);
                        describe("With EE enabled @ee", () => {
                            before(async () => {
                                // (await docSettings).validation.lint.enabled = false;
                                // (await docSettings).validation.lint.path =
                                //   "invalid-ansible-lint-path";
                                (await docSettings).validation.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                                await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckNoHost(context, validationManager, textDoc, false);
                            after(async () => {
                                // (await docSettings).validation.lint.enabled = true;
                                // (await docSettings).validation.lint.path = "ansible-lint";
                                (await docSettings).validation.enabled = true;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                        });
                        describe("With EE disabled", () => {
                            before(async () => {
                                // (await docSettings).validation.lint.enabled = false;
                                // (await docSettings).validation.lint.path =
                                //   "invalid-ansible-lint-path";
                                (await docSettings).validation.enabled = false;
                                (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                                await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                            });
                            testAnsibleSyntaxCheckNoHost(context, validationManager, textDoc, false);
                        });
                        after(async () => {
                            // (await docSettings).validation.lint.enabled = true;
                            // (await docSettings).validation.lint.path = "ansible-lint";
                            (await docSettings).validation.enabled = true;
                            (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                            await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                        });
                    }
                });
            });
        });
        describe("YAML diagnostics", () => {
            fixtureFilePath = "diagnostics/invalid_yaml.yml";
            fixtureFileUri = (0, helper_1.resolveDocUri)(fixtureFilePath);
            context = workspaceManager.getContext(fixtureFileUri);
            textDoc = (0, helper_1.getDoc)(fixtureFilePath);
            (0, chai_1.expect)(context).is.not.undefined;
            if (context) {
                docSettings = context.documentSettings.get(textDoc.uri);
                describe("With EE enabled @ee", () => {
                    before(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)("/home/runner/.ansible/collections:/usr/share/ansible");
                        await (0, helper_1.enableExecutionEnvironmentSettings)(docSettings);
                    });
                    testInvalidYamlFile(textDoc);
                    after(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                });
                describe("With EE disabled", () => {
                    before(async () => {
                        (0, helper_1.setFixtureAnsibleCollectionPathEnv)();
                        await (0, helper_1.disableExecutionEnvironmentSettings)(docSettings);
                    });
                    testInvalidYamlFile(textDoc);
                });
            }
        });
    }
});
