/*!
 * node-sass: lib/index.js
 */

var path = require('path'),
  clonedeep = require('lodash/cloneDeep'),
  assign = require('lodash/assign'),
  sass = require('./extensions');

/**
 * Require binding
 */

var binding = require('./binding')(sass);

/**
 * Get input file
 *
 * @param {Object} options
 * @api private
 */

function getInputFile(options) {
  return options.file ? path.resolve(options.file) : null;
}

/**
 * Get output file
 *
 * @param {Object} options
 * @api private
 */

function getOutputFile(options) {
  var outFile = options.outFile;

  if (!outFile || typeof outFile !== 'string' || (!options.data && !options.file)) {
    return null;
  }

  return path.resolve(outFile);
}

/**
 * Get source map
 *
 * @param {Object} options
 * @api private
 */

function getSourceMap(options) {
  var sourceMap = options.sourceMap;

  if (sourceMap && typeof sourceMap !== 'string' && options.outFile) {
    sourceMap = options.outFile + '.map';
  }

  return sourceMap && typeof sourceMap === 'string' ? path.resolve(sourceMap) : null;
}

/**
 * Get stats
 *
 * @param {Object} options
 * @api private
 */

function getStats(options) {
  var stats = {};

  stats.entry = options.file || 'data';
  stats.start = Date.now();

  return stats;
}

/**
 * End stats
 *
 * @param {Object} stats
 * @param {Object} sourceMap
 * @api private
 */

function endStats(stats) {
  stats.end = Date.now();
  stats.duration = stats.end - stats.start;

  return stats;
}

/**
 * Get style
 *
 * @param {Object} options
 * @api private
 */

function getStyle(options) {
  var styles = {
    nested: 0,
    expanded: 1,
    compact: 2,
    compressed: 3
  };

  return styles[options.outputStyle] || 0;
}

/**
 * Get indent width
 *
 * @param {Object} options
 * @api private
 */

function getIndentWidth(options) {
  var width = parseInt(options.indentWidth) || 2;

  return width > 10 ? 2 : width;
}

/**
 * Get indent type
 *
 * @param {Object} options
 * @api private
 */

function getIndentType(options) {
  var types = {
    space: 0,
    tab: 1
  };

  return types[options.indentType] || 0;
}

/**
 * Get linefeed
 *
 * @param {Object} options
 * @api private
 */

function getLinefeed(options) {
  var feeds = {
    cr: '\r',
    crlf: '\r\n',
    lf: '\n',
    lfcr: '\n\r'
  };

  return feeds[options.linefeed] || '\n';
}

/**
 * Build an includePaths string
 * from the options.includePaths array and the SASS_PATH environment variable
 *
 * @param {Object} options
 * @api private
 */

function buildIncludePaths(options) {
  options.includePaths = options.includePaths || [];

  if (process.env.hasOwnProperty('SASS_PATH')) {
    options.includePaths = options.includePaths.concat(
      process.env.SASS_PATH.split(path.delimiter)
    );
  }

  // Preserve the behaviour people have come to expect.
  // This behaviour was removed from Sass in 3.4 and
  // LibSass in 3.5.
  options.includePaths.unshift(process.cwd());

  return options.includePaths.join(path.delimiter);
}

/**
 * Get options
 *
 * @param {Object} options
 * @api private
 */

function getOptions(opts, cb) {
  if (typeof opts !== 'object') {
    throw new Error('Invalid: options is not an object.');
  }
  var options = clonedeep(opts || {});

  options.sourceComments = options.sourceComments || false;
  if (options.hasOwnProperty('file')) {
    options.file = getInputFile(options);
  }
  options.outFile = getOutputFile(options);
  options.includePaths = buildIncludePaths(options);
  options.precision = parseInt(options.precision) || 5;
  options.sourceMap = getSourceMap(options);
  options.style = getStyle(options);
  options.indentWidth = getIndentWidth(options);
  options.indentType = getIndentType(options);
  options.linefeed = getLinefeed(options);

  // context object represents node-sass environment
  options.context = { options: options, callback: cb };

  options.result = {
    stats: getStats(options)
  };

  return options;
}

/**
 * Executes a callback and transforms any exception raised into a sass error
 *
 * @param {Function} callback
 * @param {Array} arguments
 * @api private
 */

function tryCallback(callback, args) {
  try {
    return callback.apply(this, args);
  } catch (e) {
    if (typeof e === 'string') {
      return new binding.types.Error(e);
    } else if (e instanceof Error) {
      return new binding.types.Error(e.message);
    } else {
      return new binding.types.Error('An unexpected error occurred');
    }
  }
}

/**
 * Normalizes the signature of custom functions to make it possible to just supply the
 * function name and have the signature default to `fn(...)`. The callback is adjusted
 * to transform the input sass list into discrete arguments.
 *
 * @param {String} signature
 * @param {Function} callback
 * @return {Object}
 * @api private
 */

function normalizeFunctionSignature(signature, callback) {
  if (!/^\*|@warn|@error|@debug|\w+\(.*\)$/.test(signature)) {
    if (!/\w+/.test(signature)) {
      throw new Error('Invalid function signature format "' + signature + '"');
    }

    return {
      signature: signature + '(...)',
      callback: function() {
        var args = Array.prototype.slice.call(arguments),
          list = args.shift(),
          i;

        for (i = list.getLength() - 1; i >= 0; i--) {
          args.unshift(list.getValue(i));
        }

        return callback.apply(this, args);
      }
    };
  }

  return {
    signature: signature,
    callback: callback
  };
}

/**
 * Render
 *
 * @param {Object} options
 * @api public
 */

module.exports.render = function(opts, cb) {
  var options = getOptions(opts, cb);

  // options.error and options.success are for libsass binding
  options.error = function(err) {
    var payload = assign(new Error(), JSON.parse(err));

    if (cb) {
      options.context.callback.call(options.context, payload, null);
    }
  };

  options.success = function() {
    var result = options.result;
    var stats = endStats(result.stats);
    var payload = {
      css: result.css,
      map: result.map,
      stats: stats
    };

    if (cb) {
      options.context.callback.call(options.context, null, payload);
    }
  };

  var importer = options.importer;

  if (importer) {
    if (Array.isArray(importer)) {
      options.importer = [];
      importer.forEach(function(subject, index) {
        options.importer[index] = function(file, prev, bridge) {
          function done(result) {
            bridge.success(result === module.exports.NULL ? null : result);
          }

          var result = subject.call(options.context, file, prev, done);

          if (result !== undefined) {
            done(result);
          }
        };
      });
    } else {
      options.importer = function(file, prev, bridge) {
        function done(result) {
          bridge.success(result === module.exports.NULL ? null : result);
        }

        var result = importer.call(options.context, file, prev, done);

        if (result !== undefined) {
          done(result);
        }
      };
    }
  }

  var functions = clonedeep(options.functions);

  if (functions) {
    options.functions = {};

    Object.keys(functions).forEach(function(subject) {
      var cb = normalizeFunctionSignature(subject, functions[subject]);

      options.functions[cb.signature] = function() {
        var args = Array.prototype.slice.call(arguments),
          bridge = args.pop();

        function done(data) {
          bridge.success(data);
        }

        var result = tryCallback(cb.callback.bind(options.context), args.concat(done));

        if (result) {
          done(result);
        }
      };
    });
  }

  if (options.data) {
    binding.render(options);
  } else if (options.file) {
    binding.renderFile(options);
  } else {
    cb({status: 3, message: 'No input specified: provide a file name or a source string to process' });
  }
};

/**
 * Render sync
 *
 * @param {Object} options
 * @api public
 */

module.exports.renderSync = function(opts) {
  var options = getOptions(opts);
  var importer = options.importer;

  if (importer) {
    if (Array.isArray(importer)) {
      options.importer = [];
      importer.forEach(function(subject, index) {
        options.importer[index] = function(file, prev) {
          var result = subject.call(options.context, file, prev);

          return result === module.exports.NULL ? null : result;
        };
      });
    } else {
      options.importer = function(file, prev) {
        var result = importer.call(options.context, file, prev);

        return result === module.exports.NULL ? null : result;
      };
    }
  }

  var functions = clonedeep(options.functions);

  if (options.functions) {
    options.functions = {};

    Object.keys(functions).forEach(function(signature) {
      var cb = normalizeFunctionSignature(signature, functions[signature]);

      options.functions[cb.signature] = function() {
        return tryCallback(cb.callback.bind(options.context), arguments);
      };
    });
  }

  var status;
  if (options.data) {
    status = binding.renderSync(options);
  } else if (options.file) {
    status = binding.renderFileSync(options);
  } else {
    throw new Error('No input specified: provide a file name or a source string to process');
  }

  var result = options.result;

  if (status) {
    result.stats = endStats(result.stats);
    return result;
  }

  throw assign(new Error(), JSON.parse(result.error));
};

/**
 * API Info
 *
 * @api public
 */

module.exports.info = sass.getVersionInfo(binding);

/**
 * Expose sass types
 */

module.exports.types = binding.types;
module.exports.TRUE = binding.types.Boolean.TRUE;
module.exports.FALSE = binding.types.Boolean.FALSE;
module.exports.NULL = binding.types.Null.NULL;

/**
 * Polyfill the old API
 *
 * TODO: remove for 4.0
 */

function processSassDeprecationMessage() {
  console.log('Deprecation warning: `process.sass` is an undocumented internal that will be removed in future versions of Node Sass.');
}

process.sass = process.sass || {
  get versionInfo()   { processSassDeprecationMessage(); return module.exports.info; },
  get binaryName()    { processSassDeprecationMessage(); return sass.getBinaryName(); },
  get binaryUrl()     { processSassDeprecationMessage(); return sass.getBinaryUrl(); },
  get binaryPath()    { processSassDeprecationMessage(); return sass.getBinaryPath(); },
  get getBinaryPath() { processSassDeprecationMessage(); return sass.getBinaryPath; },
};
