"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.noop = exports.resolveAllAssetFiles = exports.resolveAllPaperclipFiles = void 0;
var path = require("path");
var url = require("url");
var paperclip_utils_1 = require("paperclip-utils");
var fs = require("fs");
// TODO - move to paperclip-utils as soon as we have a glob library that can handle virtual file systems
var findResourcesFromConfig = function (get) { return function (fs) { return function (fromUri, relative) {
    // symlinks may fudge module resolution, so we need to find the real path
    var fromPath = fs.realpathSync(new url.URL(fromUri));
    var fromPathDirname = path.dirname(fromPath);
    var configUrl = paperclip_utils_1.findPCConfigUrl(fs)(fromUri);
    // If there's no config, then don't bother looking for PC files. Otherwise we're likely
    // to need esoteric logic for resolving PC that I don't think should be supported -- there should
    // just be aproach.
    if (!configUrl) {
        return [];
    }
    var configUri = new url.URL(configUrl);
    var config = JSON.parse(fs.readFileSync(configUri, "utf8"));
    return get(config, path.dirname(url.fileURLToPath(configUri)))
        .filter(function (pathname) { return pathname !== fromPath; })
        .map(function (pathname) {
        if (relative) {
            var modulePath = getModulePath(configUrl, config, pathname, fromPathDirname);
            if (!path.isAbsolute(modulePath)) {
                return modulePath;
            }
            var relativePath = path.relative(fromPathDirname, modulePath);
            if (relativePath.charAt(0) !== ".") {
                relativePath = "./" + relativePath;
            }
            return relativePath;
        }
        return url.pathToFileURL(pathname).href;
    })
        .map(function (filePath) {
        return filePath.replace(/\\/g, "/");
    });
}; }; };
var resolveModuleRoots = function (fromDir, roots) {
    if (roots === void 0) { roots = []; }
    var stat = fs.lstatSync(fromDir);
    var realpath = stat.isSymbolicLink() ? fs.realpathSync(fromDir) : fromDir;
    var newStat = realpath === fromDir ? stat : fs.lstatSync(realpath);
    if (!newStat.isDirectory()) {
        return roots;
    }
    if (fs.existsSync(path.join(fromDir, "package.json"))) {
        roots.push(fromDir);
    }
    else {
        for (var _i = 0, _a = fs.readdirSync(realpath); _i < _a.length; _i++) {
            var dirname = _a[_i];
            resolveModuleRoots(path.join(fromDir, dirname), roots);
        }
    }
    return roots;
};
var filterAllFiles = function (filter) {
    var scan = function (currentPath, results) {
        if (results === void 0) { results = []; }
        var stat = fs.lstatSync(currentPath);
        var realpath = stat.isSymbolicLink()
            ? fs.realpathSync(currentPath)
            : currentPath;
        var newStat = realpath === currentPath ? stat : fs.lstatSync(realpath);
        if (newStat.isDirectory()) {
            for (var _i = 0, _a = fs.readdirSync(realpath); _i < _a.length; _i++) {
                var dirname = _a[_i];
                var dirpath = path.join(currentPath, dirname);
                scan(dirpath, results);
            }
        }
        else {
            if (filter(currentPath)) {
                results.push(currentPath);
            }
        }
        return results;
    };
    return scan;
};
var resolveResources = function (config, cwd, filterFiles) {
    var sourceDir = config.sourceDirectory === "."
        ? cwd
        : path.join(cwd, config.sourceDirectory);
    var filePaths = filterFiles(sourceDir);
    if (config.moduleDirectories) {
        for (var _i = 0, _a = config.moduleDirectories; _i < _a.length; _i++) {
            var modulesDirname = _a[_i];
            var moduleDirPath = path.join(cwd, modulesDirname);
            var moduleRoots = resolveModuleRoots(moduleDirPath);
            for (var _b = 0, moduleRoots_1 = moduleRoots; _b < moduleRoots_1.length; _b++) {
                var moduleDir = moduleRoots_1[_b];
                // need to scan until there's a package. This covers @organization namespaces.
                if (!moduleDir) {
                    continue;
                }
                var pcConfigPath = path.join(moduleDir, paperclip_utils_1.PC_CONFIG_FILE_NAME);
                if (!fs.existsSync(pcConfigPath)) {
                    continue;
                }
                var moduleConfig = JSON.parse(fs.readFileSync(pcConfigPath, "utf8"));
                var moduleSources = filterFiles(path.join(moduleDir, moduleConfig.sourceDirectory));
                filePaths.push.apply(filePaths, moduleSources);
            }
        }
    }
    return filePaths;
};
exports.resolveAllPaperclipFiles = findResourcesFromConfig(function (config, cwd) {
    return resolveResources(config, cwd, filterAllFiles(function (filePath) { return path.extname(filePath) === ".pc"; }));
});
exports.resolveAllAssetFiles = findResourcesFromConfig(function (config, cwd) {
    // const ext = `+(jpg|jpeg|png|gif|svg)`;
    var exts = [".jpg", ".jpeg", ".png", ".gif", ".svg", ".ttf"];
    // const sourceDir = config.sourceDirectory;
    return resolveResources(config, cwd, filterAllFiles(function (filePath) { return exts.includes(path.extname(filePath)); }));
    // if (sourceDir === ".") {
    //   return filterAllFiles(filePath => exts.includes(path.extname(filePath)))(cwd);
    //   // return glob.sync(`**/*.${ext}`, { cwd, realpath: true });
    // }
    // // return glob.sync(`${sourceDir}/**/*.${ext}`, { cwd, realpath: true });
    // return filterAllFiles(filePath => exts.includes(path.extname(filePath)))(path.join(cwd, sourceDir));
});
var getModulePath = function (configUri, config, fullPath, fromDir) {
    var _a;
    var configDir = path.dirname(url.fileURLToPath(configUri));
    var moduleDirectory = path.join(configDir, config.sourceDirectory) + "/";
    if (fullPath.indexOf(moduleDirectory) === 0) {
        var modulePath = fullPath.replace(moduleDirectory, "");
        var relativePath = path.relative(fromDir, fullPath);
        if (((_a = relativePath.match(/\.\.\//g)) === null || _a === void 0 ? void 0 : _a.length) > 0) {
            return modulePath;
        }
    }
    if (config.moduleDirectories) {
        for (var _i = 0, _b = config.moduleDirectories; _i < _b.length; _i++) {
            var moduleDirectory_1 = _b[_i];
            var fullModulePath = path.join(configDir, moduleDirectory_1);
            if (fullPath.indexOf(fullModulePath) === 0) {
                return fullPath.replace(fullModulePath, "").substr(1);
            }
        }
    }
    return fullPath;
};
// eslint-disable-next-line
exports.noop = function () { };
