const fs = require("fs");
const path = require("path");
const env = require("process");
const expect = require("chai").expect;
const Ajv = require("ajv").default;
const ajv = new Ajv({ allErrors: true });
require("ajv-errors")(ajv);

//let root, slug;
//let workingDirectory = path.join(root, slug);
//console.log(`👷‍♂️ Working with ‘${slug}’ slug.`);

const themeSchemaFile = "src/test_manifest_job/json_theme_schema.jsonc";
let wppManifest;
let validator;
let files;

function leftOuterJoin(leftArray, rightArray) {
    return leftArray.filter(function (el) {
        return this.indexOf(el) < 0;
    }, rightArray);
}

function flatReferences(wppManifest) {
    allImageIds = [
        wppManifest.dayHighlight,
        wppManifest.nightHighlight,
        ...wppManifest.dayImageList,
        ...wppManifest.nightImageList,
        ...(wppManifest.sunsetImageList || []),
        ...(wppManifest.sunriseImageList || [])
    ];
    return allImageIds.filter(el => el !== undefined).map(el => {
        return wppManifest.imageFilename.replace("*", el);
    });
}

describe('Mandatory Checks', function () {
    before(function () {
        const slug = env.PACKAGE_NAME;
        expect(slug).to.be.a("string").that.is.not.empty;
        const root = env.ENTRY_FOLDER;
        expect(root).to.be.a("string").that.is.not.empty;
        const workingDirectory = path.join(root, slug);
        const files = fs.readdirSync(workingDirectory);
        expect(files).to.be.an('array').that.is.not.empty;
        let validator = ajv.compile(JSON.parse(fs.readFileSync(themeSchemaFile, 'utf8')));
    });

    step('Manifest is an existing json file', function () {
        wppManifest = JSON.parse(fs.readFileSync(path.join(workingDirectory, "theme.json"), "utf8"));
    });

    step('Manifest passes the schema', function () {
        const isValid = validator(wppManifest);
        if (!isValid) expect.fail(`\n\t• ${validator.errors.map(el => { return el.message; }).join('\n\t• ')}`);
    });

    step('There are no missing files', function () {
        let references = flatReferences(wppManifest);
        references.push("theme.json");
        let missings = leftOuterJoin(references, files);
        expect(missings,
            `The following reference${(missings.length > 1) ? "s" : ""} from theme.json ${(missings.length > 1) ? "are" : "is"} missing in the pack. Consider adding ${(missings.length > 1) ? "them" : " it"} to the pack or removing the reference${(missings.length > 1) ? "s" : ""} from the theme.json:\n\t• ${missings.join('\n\t• ')}\n`
        ).to.be.lengthOf(0,);
    });

    step('There are no orphan files', function () {
        let references = flatReferences(wppManifest);
        let orphans = leftOuterJoin(files.filter(x => x !== "theme.json"), references);
        expect(orphans,
            `The following orphan file${(orphans.length > 1) ? "s are" : " is"} not referenced in this theme.json. Consider removing the file${(orphans.length > 1) ? "s" : ""} or referencing ${(orphans.length > 1) ? "them" : "it"} in the theme.json:\n\t• ${orphans.join('\n\t• ')}\n`
        ).to.be.lengthOf(0);
    });

});