"use strict";

var _slice = Array.prototype.slice;
var _classProps = function (child, staticProps, instanceProps) {
  if (staticProps) Object.defineProperties(child, staticProps);
  if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

var Declaration = require("./declaration");
var Comment = require("./comment");
var AtRule = require("./at-rule");
var Result = require("./result");
var Rule = require("./rule");
var Root = require("./root");

// List of functions to process CSS
var PostCSS = (function () {
  var PostCSS = function PostCSS(processors) {
    var _this = this;
    if (processors === undefined) processors = [];
    this.processors = processors.map(function (i) {
      return _this.normalize(i);
    });
  };

  _classProps(PostCSS, null, {
    use: {
      writable: true,


      // Add another function to CSS processors
      value: function (processor) {
        processor = this.normalize(processor);
        if (processor instanceof PostCSS) {
          this.processors = this.processors.concat(processor.processors);
        } else {
          this.processors.push(processor);
        }
        return this;
      }
    },
    process: {
      writable: true,


      // Process CSS throw installed processors
      value: function (css, opts) {
        if (opts === undefined) opts = {};
        if (opts.map == "inline") {
          opts.map = { inline: true };
          console.warn("Shortcut map: \"inline\" is deprecated " + "and will be remove in 3.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 i = 0; i < this.processors.length; i++) {
          var returned = this.processors[i](parsed, opts);
          if (returned instanceof Root) parsed = returned;
        }

        return parsed.toResult(opts);
      }
    },
    normalize: {
      writable: true,


      // Return processor function
      value: function (processor) {
        var type = typeof (processor);
        if ((type == "object" || type == "function") && processor.postcss) {
          return processor.postcss;
        } else {
          return processor;
        }
      }
    }
  });

  return PostCSS;
})();

// Framework for CSS postprocessors
//
//   var processor = postcss(function (css) {
//       // Change nodes in css
//   });
//   processor.process(css)
var postcss = function () {
  var processors = _slice.call(arguments);

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

// Compile CSS to nodes
postcss.parse = require("./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;