"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const decamelize_1 = __importDefault(require("decamelize"));
const fileUtils_1 = require("./fileUtils");
const Constants_1 = require("./Constants");
class ComponentIndex {
    constructor(project) {
        this.project = project;
    }
    getProjectMetadata() {
        const metadata = this.findProjectMetadata();
        if (metadata.packages.length > 0) {
            const componentsMetadata = this.getModules();
            metadata.packages[0].components = componentsMetadata;
        }
        return metadata;
    }
    getModules() {
        let modulesSourceDirectory = this.project.modulesSourceDirectory;
        const moduleDirectories = [];
        if (this.project.isSfdx) {
            const lwcPath = fileUtils_1.findLWCFolderPath(this.project.modulesSourceDirectory);
            if (lwcPath) {
                moduleDirectories.push(lwcPath);
            }
            else {
                console.warn(`no 'lwc' directory found in path ${modulesSourceDirectory}`);
            }
        }
        else {
            moduleDirectories.push(...this.findSubdirectories(modulesSourceDirectory));
        }
        return this.findModulesIn(moduleDirectories);
    }
    findModulesIn(namespaceRoots) {
        const files = [];
        namespaceRoots.forEach(namespaceRoot => {
            const subdirs = this.findSubdirectories(namespaceRoot);
            for (const subdir of subdirs) {
                const basename = path_1.default.basename(subdir);
                const modulePath = path_1.default.join(subdir, basename + '.js');
                if (fs_extra_1.default.pathExistsSync(modulePath) &&
                    this.isJSComponent(modulePath) &&
                    this.isUIComponent(modulePath)) {
                    const name = basename;
                    let namespace = path_1.default.basename(path_1.default.dirname(subdir));
                    if (this.project.isSfdx) {
                        namespace = this.project.configuration.namespace;
                    }
                    const jsName = `${namespace}/${name}`;
                    const decamelizedName = decamelize_1.default(name, '-');
                    const htmlName = `${namespace}-${decamelizedName}`;
                    const url = `/preview/${namespace}/${name}`;
                    files.push({
                        jsName,
                        htmlName,
                        namespace,
                        name,
                        url,
                        path: path_1.default.normalize(modulePath)
                    });
                }
            }
        });
        return files;
    }
    findSubdirectories(dir) {
        const subdirs = [];
        if (!fs_extra_1.default.existsSync(dir)) {
            return subdirs;
        }
        const dirs = fs_extra_1.default.readdirSync(dir);
        for (const file of dirs) {
            const subdir = path_1.default.join(dir, file);
            if (fs_extra_1.default.statSync(subdir).isDirectory()) {
                subdirs.push(subdir);
            }
        }
        return subdirs;
    }
    isJSComponent(file) {
        if (!file.toLowerCase().endsWith('.js')) {
            return false;
        }
        return this.nameFromFile(file) != null;
    }
    isUIComponent(file) {
        try {
            const fileContent = fs_extra_1.default.readFileSync(file);
            return fileContent.indexOf('LightningElement') > -1;
        }
        catch (e) {
            return true;
        }
    }
    nameFromFile(file) {
        const filePath = path_1.default.parse(file);
        const fileName = filePath.name;
        const pathElements = this.splitPath(filePath);
        const parentDirName = pathElements.pop();
        if (fileName === parentDirName) {
            const namespace = pathElements.pop();
            return namespace + '/' + parentDirName;
        }
        return null;
    }
    splitPath(filePath) {
        let pathElements = filePath.dir.split(path_1.default.sep);
        if (path_1.default.sep === '\\' && filePath.dir.indexOf('\\') === -1) {
            pathElements = filePath.dir.split('/');
        }
        return pathElements;
    }
    findProjectMetadata() {
        const root = this.project.projectDirectory;
        let projectName = path_1.default.basename(root);
        const packageJsonPath = path_1.default.join(root, 'package.json');
        try {
            const packageJson = JSON.parse(fs_extra_1.default.readFileSync(packageJsonPath, 'utf8'));
            if (packageJson.name) {
                projectName = packageJson.name;
            }
        }
        catch (e) {
            console.error(`Loading ${packageJsonPath} failed JSON parsing with error ${e.message}`);
        }
        const packages = [];
        const metadata = {
            projectName,
            packages
        };
        let defaultPackageName = 'Default';
        if (this.project.isSfdx) {
            const sfdxProjectPath = path_1.default.join(root, Constants_1.SFDX_PROJECT_JSON);
            if (fs_extra_1.default.existsSync(sfdxProjectPath)) {
                try {
                    const sfdxJson = JSON.parse(fs_extra_1.default.readFileSync(sfdxProjectPath, 'utf8'));
                    if (sfdxJson.packageDirectories instanceof Array) {
                        let sfdxDefaultPackage;
                        if (sfdxJson.packageDirectories.length === 1) {
                            sfdxDefaultPackage = sfdxJson.packageDirectories[0];
                        }
                        else {
                            sfdxDefaultPackage = sfdxJson.packageDirectories.find((pkg) => !!pkg.default);
                        }
                        if (sfdxDefaultPackage) {
                            if (sfdxDefaultPackage.package) {
                                defaultPackageName = sfdxDefaultPackage.package;
                            }
                            else if (sfdxDefaultPackage.path) {
                                defaultPackageName = path_1.default.basename(sfdxDefaultPackage.path);
                            }
                        }
                    }
                }
                catch (e) {
                    console.error(`Loading ${sfdxProjectPath} failed JSON parsing with error ${e.message}`);
                }
            }
        }
        const defaultPackage = {
            key: 'package_1',
            packageName: defaultPackageName,
            components: [],
            isDefault: true
        };
        packages.push(defaultPackage);
        return metadata;
    }
}
exports.default = ComponentIndex;
//# sourceMappingURL=ComponentIndex.js.map