"use strict";

var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };

var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };

var Declaration = _interopRequire(require("./declaration"));

var Comment = _interopRequire(require("./comment"));

var AtRule = _interopRequire(require("./at-rule"));

var Result = _interopRequire(require("./result"));

var parse = _interopRequire(require("./parse"));

var Rule = _interopRequire(require("./rule"));

var Root = _interopRequire(require("./root"));

// List of functions to process CSS

var PostCSS = (function () {
    function PostCSS() {
        var _this = this;

        var plugins = arguments[0] === undefined ? [] : arguments[0];

        _classCallCheck(this, PostCSS);

        this.plugins = plugins.map(function (i) {
            return _this.normalize(i);
        });
    }

    // Add function as PostCSS plugins

    PostCSS.prototype.use = function use(plugin) {
        plugin = this.normalize(plugin);
        if (typeof plugin == "object" && Array.isArray(plugin.plugins)) {
            this.plugins = this.plugins.concat(plugin.plugins);
        } else {
            this.plugins.push(plugin);
        }
        return this;
    };

    // Process CSS throw installed plugins

    PostCSS.prototype.process = function process(css) {
        var opts = arguments[1] === undefined ? {} : arguments[1];

        var parsed;
        if (css instanceof Root) {
            parsed = css;
        } else if (css instanceof Result) {
            parsed = css.root;
            if (css.map && typeof opts.map == "undefined") {
                opts.map = { prev: css.map };
            }
        } else {
            parsed = postcss.parse(css, opts);
        }

        for (var _iterator = this.plugins, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
            var _ref;

            if (_isArray) {
                if (_i >= _iterator.length) break;
                _ref = _iterator[_i++];
            } else {
                _i = _iterator.next();
                if (_i.done) break;
                _ref = _i.value;
            }

            var plugin = _ref;

            var returned = plugin(parsed, opts);
            if (returned instanceof Root) parsed = returned;
        }

        return parsed.toResult(opts);
    };

    // Return plugin function

    PostCSS.prototype.normalize = function normalize(plugin) {
        var type = typeof plugin;
        if ((type == "object" || type == "function") && plugin.postcss) {
            return plugin.postcss;
        } else {
            return plugin;
        }
    };

    return PostCSS;
})();

// Framework for CSS postprocessors
//
//   var processor = postcss(function (css) {
//       // Change nodes in css
//   });
//   processor.process(css)
var postcss = function postcss() {
    for (var _len = arguments.length, plugins = Array(_len), _key = 0; _key < _len; _key++) {
        plugins[_key] = arguments[_key];
    }

    if (plugins.length == 1 && Array.isArray(plugins[0])) {
        plugins = plugins[0];
    }
    return new PostCSS(plugins);
};

// Compile CSS to nodes
postcss.parse = parse;

// Nodes shortcuts
postcss.comment = function (defaults) {
    return new Comment(defaults);
};
postcss.atRule = function (defaults) {
    return new AtRule(defaults);
};
postcss.decl = function (defaults) {
    return new Declaration(defaults);
};
postcss.rule = function (defaults) {
    return new Rule(defaults);
};
postcss.root = function (defaults) {
    return new Root(defaults);
};

module.exports = postcss;