/**
 * Clean-css - https://github.com/clean-css/clean-css
 * Released under the terms of MIT license
 */

var level0Optimize = require('./optimizer/level-0/optimize');
var level1Optimize = require('./optimizer/level-1/optimize');
var level2Optimize = require('./optimizer/level-2/optimize');
var validator = require('./optimizer/validator');

var compatibilityFrom = require('./options/compatibility');
var fetchFrom = require('./options/fetch');
var formatFrom = require('./options/format').formatFrom;
var inlineFrom = require('./options/inline');
var inlineRequestFrom = require('./options/inline-request');
var inlineTimeoutFrom = require('./options/inline-timeout');
var OptimizationLevel = require('./options/optimization-level').OptimizationLevel;
var optimizationLevelFrom = require('./options/optimization-level').optimizationLevelFrom;
var pluginsFrom = require('./options/plugins');
var rebaseFrom = require('./options/rebase');
var rebaseToFrom = require('./options/rebase-to');

var inputSourceMapTracker = require('./reader/input-source-map-tracker');
var readSources = require('./reader/read-sources');

var serializeStyles = require('./writer/simple');
var serializeStylesAndSourceMap = require('./writer/source-maps');

var CleanCSS = module.exports = function CleanCSS(options) {
  options = options || {};

  this.options = {
    batch: !!options.batch,
    compatibility: compatibilityFrom(options.compatibility),
    explicitRebaseTo: 'rebaseTo' in options,
    fetch: fetchFrom(options.fetch),
    format: formatFrom(options.format),
    inline: inlineFrom(options.inline),
    inlineRequest: inlineRequestFrom(options.inlineRequest),
    inlineTimeout: inlineTimeoutFrom(options.inlineTimeout),
    level: optimizationLevelFrom(options.level),
    plugins: pluginsFrom(options.plugins),
    rebase: rebaseFrom(options.rebase, options.rebaseTo),
    rebaseTo: rebaseToFrom(options.rebaseTo),
    returnPromise: !!options.returnPromise,
    sourceMap: !!options.sourceMap,
    sourceMapInlineSources: !!options.sourceMapInlineSources
  };
};


// for compatibility with optimize-css-assets-webpack-plugin
CleanCSS.process = function (input, opts) {
  var cleanCss;
  var optsTo = opts.to;

  delete opts.to;
  cleanCss = new CleanCSS(Object.assign({ returnPromise: true, rebaseTo: optsTo }, opts));

  return cleanCss.minify(input)
    .then(function(output) {
      return { css: output.styles };
    });
};


CleanCSS.prototype.minify = function (input, maybeSourceMap, maybeCallback) {
  var options = this.options;

  if (options.returnPromise) {
    return new Promise(function (resolve, reject) {
      minifyAll(input, options, maybeSourceMap, function (errors, output) {
        return errors ?
          reject(errors) :
          resolve(output);
      });
    });
  } else {
    return minifyAll(input, options, maybeSourceMap, maybeCallback);
  }
};

function minifyAll(input, options, maybeSourceMap, maybeCallback) {
  if (options.batch && Array.isArray(input)) {
    return minifyInBatchesFromArray(input, options, maybeSourceMap, maybeCallback);
  } else if (options.batch && (typeof input == 'object')) {
    return minifyInBatchesFromHash(input, options, maybeSourceMap, maybeCallback);
  } else {
    return minify(input, options, maybeSourceMap, maybeCallback);
  }
}

function minifyInBatchesFromArray(input, options, maybeSourceMap, maybeCallback) {
  var callback = typeof maybeCallback == 'function' ?
    maybeCallback :
    (typeof maybeSourceMap == 'function' ? maybeSourceMap : null);
  var errors = [];
  var outputAsHash = {};
  var inputValue;
  var i, l;

  function whenHashBatchDone(innerErrors, output) {
    outputAsHash = Object.assign(outputAsHash, output);

    if (innerErrors !== null) {
      errors = errors.concat(innerErrors);
    }
  }

  for (i = 0, l = input.length; i < l; i++) {
    if (typeof input[i] == 'object') {
      minifyInBatchesFromHash(input[i], options, whenHashBatchDone);
    } else {
      inputValue = input[i];

      outputAsHash[inputValue] = minify([inputValue], options);
      errors = errors.concat(outputAsHash[inputValue].errors);
    }
  }

  return callback ?
    callback(errors.length > 0 ? errors : null, outputAsHash) :
    outputAsHash;
}

function minifyInBatchesFromHash(input, options, maybeSourceMap, maybeCallback) {
  var callback = typeof maybeCallback == 'function' ?
    maybeCallback :
    (typeof maybeSourceMap == 'function' ? maybeSourceMap : null);
  var errors = [];
  var outputAsHash = {};
  var inputKey;
  var inputValue;

  for (inputKey in input) {
    inputValue = input[inputKey];

    outputAsHash[inputKey] = minify(inputValue.styles, options, inputValue.sourceMap);
    errors = errors.concat(outputAsHash[inputKey].errors);
  }

  return callback ?
    callback(errors.length > 0 ? errors : null, outputAsHash) :
    outputAsHash;
}

function minify(input, options, maybeSourceMap, maybeCallback) {
  var sourceMap = typeof maybeSourceMap != 'function' ?
    maybeSourceMap :
    null;
  var callback = typeof maybeCallback == 'function' ?
    maybeCallback :
    (typeof maybeSourceMap == 'function' ? maybeSourceMap : null);
  var context = {
    stats: {
      efficiency: 0,
      minifiedSize: 0,
      originalSize: 0,
      startedAt: Date.now(),
      timeSpent: 0
    },
    cache: {
      specificity: {}
    },
    errors: [],
    inlinedStylesheets: [],
    inputSourceMapTracker: inputSourceMapTracker(),
    localOnly: !callback,
    options: options,
    source: null,
    sourcesContent: {},
    validator: validator(options.compatibility),
    warnings: []
  };
  var implicitRebaseToWarning;

  if (sourceMap) {
    context.inputSourceMapTracker.track(undefined, sourceMap);
  }

  if (options.rebase && !options.explicitRebaseTo) {
    implicitRebaseToWarning =
      'You have set `rebase: true` without giving `rebaseTo` option, which, in this case, defaults to the current working directory. ' +
      'You are then warned this can lead to unexpected URL rebasing (aka here be dragons)! ' +
      'If you are OK with the clean-css output, then you can get rid of this warning by giving clean-css a `rebaseTo: process.cwd()` option.';
    context.warnings.push(implicitRebaseToWarning);
  }

  return runner(context.localOnly)(function () {
    return readSources(input, context, function (tokens) {
      var serialize = context.options.sourceMap ?
        serializeStylesAndSourceMap :
        serializeStyles;

      var optimizedTokens = optimize(tokens, context);
      var optimizedStyles = serialize(optimizedTokens, context);
      var output = withMetadata(optimizedStyles, context);

      return callback ?
        callback(context.errors.length > 0 ? context.errors : null, output) :
        output;
    });
  });
}

function runner(localOnly) {
  // to always execute code asynchronously when a callback is given
  // more at blog.izs.me/post/59142742143/designing-apis-for-asynchrony
  return localOnly ?
    function (callback) { return callback(); } :
    process.nextTick;
}

function optimize(tokens, context) {
  var optimized = level0Optimize(tokens, context);

  optimized = OptimizationLevel.One in context.options.level ?
    level1Optimize(tokens, context) :
    tokens;
  optimized = OptimizationLevel.Two in context.options.level ?
    level2Optimize(tokens, context, true) :
    optimized;

  return optimized;
}

function withMetadata(output, context) {
  output.stats = calculateStatsFrom(output.styles, context);
  output.errors = context.errors;
  output.inlinedStylesheets = context.inlinedStylesheets;
  output.warnings = context.warnings;

  return output;
}

function calculateStatsFrom(styles, context) {
  var finishedAt = Date.now();
  var timeSpent = finishedAt - context.stats.startedAt;

  delete context.stats.startedAt;
  context.stats.timeSpent = timeSpent;
  context.stats.efficiency = 1 - styles.length / context.stats.originalSize;
  context.stats.minifiedSize = styles.length;

  return context.stats;
}
