/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var fs = require('fs');
var path = require('path');
var join = path.join;
var Vinyl = require('vinyl');
var through = require('through2');
var util = require('./util');
var colors = util.colors;
var transport = require('./transport');
var debug = util.debug;

// empty buffer
var NULL = new Buffer('');

function include(options){
  var initialized = false;

  return through.obj(function (vinyl, encoding, callback){
    if (vinyl.isNull()) {
      // return empty file
      return callback(null, vinyl);
    }

    if (vinyl.isStream()) {
      return callback(util.throwError('streaming not supported.'));
    }

    if (!initialized) {
      // format ignore
      options.ignore = options.ignore.map(function (id){
        var alias = options.alias;
        var paths = options.paths;
        var vars = options.vars;

        // parse id form alias, paths, vars
        id = util.parseAlias(id, alias);
        id = util.parsePaths(id, paths);
        id = util.parseAlias(id, alias);
        id = util.parseVars(id, vars);
        id = util.parseAlias(id, alias);

        var path;

        if (util.isAbsolute(id)) {
          path = join(options.wwwroot, id.substring(1));
        } else {
          path = join(vinyl.cwd, vinyl.base, id);
        }

        return util.normalize(util.addExt(path));
      });

      initialized = true;
    }

    vinyl = transport(vinyl, options);

    var included = [];
    var startVinyl = vinyl.clone();
    var endVinyl = vinyl.clone();

    startVinyl.concatOpen = true;
    endVinyl.concatClose = true;
    endVinyl.contents = NULL;

    this.push(startVinyl);
    included.push(util.normalize(startVinyl.path));
    includeDeps.call(this, vinyl, options, included);
    this.push(endVinyl);

    callback();
  });
}

/**
 * include dependencies file
 * @param vinyl
 * @param options
 * @param included
 */

function includeDeps(vinyl, options, included){
  var stream = this;
  var pkg = vinyl.package;
  var include = options.include;

  // traverse
  function traverse(path, base){
    included.push(util.normalize(path));

    var vinyl = vinylFile(path, base);

    if (vinyl !== null) {
      vinyl = transport(vinyl, options);

      includeDeps.call(stream, vinyl, options, included);
      stream.push(vinyl);
    }
  }

  if (pkg && Array.isArray(pkg.localDepsMaps)) {
    pkg.localDepsMaps.forEach(function (meta){
      // ignore or included
      if (options.ignore.indexOf(meta.path) !== -1 || included.indexOf(meta.path) !== -1) {
        return false;
      }

      switch (include) {
        case 'all':
          traverse(meta.path, vinyl);
          break;
        case 'self':
          break;
        case 'relative':
        default :
          if (util.isRelative(meta.id)) {
            traverse(meta.path, vinyl);
          }

          break;
      }
    });
  }
}

/**
 * create a new vinyl file
 * @param path
 * @param vinyl
 * @returns {*}
 */

function vinylFile(path, vinyl){
  if (!is.string(path) || !vinyl) return null;

  if (!fs.existsSync(path)) {
    path = util.hideExt(path);
  }

  if (fs.existsSync(path)) {
    return new Vinyl({
      path: path,
      cwd: vinyl.cwd,
      base: vinyl.base,
      stat: fs.statSync(path),
      contents: fs.readFileSync(path)
    });
  }

  debug('file: %s not exists', colors.warn(path));

  return null;
}

/**
 * Exports module.
 */

module.exports = include;
@@ -714,24 +714,48 @@
 tialized) %7B%0A
+      var ignore = %5B%5D;%0A%0A
       // for
@@ -789,44 +789,49 @@
 nore
- = options.ignore.map(function (id)%7B
+.forEach(function (id)%7B%0A        var path;
 %0A   
@@ -1183,27 +1183,8 @@
 );%0A%0A
-        var path;%0A%0A
     
@@ -1285,16 +1285,42 @@
   %7D else
+ if (!util.isRelative(id))
  %7B%0A     
@@ -1383,23 +1383,50 @@
         
-return 
+if (path) %7B%0A          ignore.push(
 util.nor
@@ -1450,24 +1450,25 @@
 t(path))
+)
 ;%0A      
 %7D);%0A%0A   
@@ -1459,18 +1459,60 @@
 ;%0A      
-%7D)
+  %7D%0A      %7D);%0A%0A      options.ignore = ignore
 ;%0A%0A     

add source file