"use strict";
var d = require("debug");
var postcss_1 = require("postcss");
var postCssValuesParser = require("postcss-values-parser");
var isUrl = require("is-url");
var debug = d('detective-postcss');
function detective(src, options) {
    if (options === void 0) { options = { url: false }; }
    var references = [];
    var root;
    try {
        root = postcss_1.parse(src);
    }
    catch (e) {
        throw new detective.MalformedCssError();
    }
    root.walkAtRules(function (rule) {
        var file = null;
        if (isImportRule(rule)) {
            var firstNode = parseValue(rule.params).first;
            file = getValueOrUrl(firstNode);
            if (file) {
                debug("found %s of %s", '@import', file);
            }
        }
        if (isValueRule(rule)) {
            var lastNode = parseValue(rule.params).last;
            if (isFrom(lastNode.prev())) {
                file = getValueOrUrl(lastNode);
                if (file) {
                    debug("found %s of %s", '@value with import', file);
                }
            }
            if (options.url && isUrlNode(lastNode)) {
                file = getValueOrUrl(lastNode);
                if (file) {
                    debug("found %s of %s", 'url() with import', file);
                }
            }
        }
        file && references.push(file);
    });
    if (options.url) {
        root.walkDecls(function (decl) {
            var nodes = parseValue(decl.value).nodes;
            var files = nodes.filter(isUrlNode).map(getValueOrUrl);
            if (files) {
                files.forEach(function (file) {
                    return debug("found %s of %s", 'url() with import', file);
                });
                references = references.concat(files);
            }
        });
    }
    return references;
}
function parseValue(value) {
    return postCssValuesParser(value).parse().first;
}
function getValueOrUrl(node) {
    var ret;
    if (isUrlNode(node)) {
        // ['(', 'file', ')']
        ret = node.nodes[1].value;
    }
    else {
        ret = node.value;
    }
    // is-url sometimes gets data: URLs wrong
    return !isUrl(ret) && !ret.startsWith('data:') && ret;
}
function isUrlNode(node) {
    return node.type === 'func' && node.value === 'url';
}
function isValueRule(rule) {
    return rule.name === 'value';
}
function isImportRule(rule) {
    return rule.name === 'import';
}
function isFrom(node) {
    return node.type == 'word' && node.value === 'from';
}
(function (detective) {
    var MalformedCssError = /** @class */ (function () {
        function MalformedCssError() {
        }
        return MalformedCssError;
    }());
    detective.MalformedCssError = MalformedCssError;
    MalformedCssError.prototype = Object.create(Error.prototype);
})(detective || (detective = {}));
module.exports = detective;