"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetadataLibrary = void 0;
const fs_1 = require("fs");
const vscode_uri_1 = require("vscode-uri");
const yaml_1 = require("yaml");
const misc_1 = require("../utils/misc");
class MetadataLibrary {
    connection;
    // cache of metadata contents per metadata file
    metadata = new Map();
    constructor(connection) {
        this.connection = connection;
    }
    get(uri) {
        const metadataUri = this.getAnsibleMetadataUri(uri);
        if (metadataUri) {
            let metadata = this.metadata.get(metadataUri);
            if (!metadata) {
                metadata = this.readAnsibleMetadata(metadataUri);
                this.metadata.set(metadataUri, metadata);
            }
            return metadata;
        }
    }
    handleWatchedDocumentChange(params) {
        for (const fileEvent of params.changes) {
            // remove from cache on any change
            this.metadata.delete(fileEvent.uri);
        }
    }
    /**
     * Finds a path where the metadata file for a given document should reside.
     * @returns The path or undefined in case the file cannot have any related
     * metadata file.
     */
    getAnsibleMetadataUri(uri) {
        let metaPath;
        const pathArray = uri.split("/");
        // Find first
        for (let index = pathArray.length - 1; index >= 0; index--) {
            if (pathArray[index] === "tasks") {
                metaPath = pathArray
                    .slice(0, index)
                    .concat("meta", "main.yml")
                    .join("/");
            }
        }
        return metaPath;
    }
    async readAnsibleMetadata(metadataUri) {
        const metadata = {
            source: metadataUri,
            collections: new Array(),
        };
        const metadataFilePath = vscode_uri_1.URI.parse(metadataUri).path;
        if (await (0, misc_1.fileExists)(metadataFilePath)) {
            try {
                const metaContents = await fs_1.promises.readFile(metadataFilePath, {
                    encoding: "utf8",
                });
                (0, yaml_1.parseAllDocuments)(metaContents).forEach((metaDoc) => {
                    const metaObject = metaDoc.toJSON();
                    if ((0, misc_1.hasOwnProperty)(metaObject, "collections") &&
                        metaObject.collections instanceof Array) {
                        metaObject.collections.forEach((collection) => {
                            if (typeof collection === "string") {
                                metadata.collections.push(collection);
                            }
                        });
                    }
                });
            }
            catch (error) {
                let msg = "";
                if (error instanceof Error) {
                    msg = error.message;
                }
                else {
                    msg = `${error}`;
                }
                this.connection.window.showErrorMessage(msg);
            }
        }
        return metadata;
    }
}
exports.MetadataLibrary = MetadataLibrary;
