var urlParser = require("url");

var $ = require("cheerio");

var request = require("./utils/request");
var error = require("./utils/errors");

/**
 * get favicon path or buffer
 * @param  {[type]}   domain   [description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
exports.favicon = function(domain, callback) {
  if(typeof domain !== "string" || typeof callback !== "function") {
    return callback(error.MISSING_PARAMS());
  }
  if(domain.substring(0, 4) !== "http") {
    domain = "http://" + domain;
  }
  followRedirectUrl(domain, function(err, url) {
    if(err) { return callback(err); }
    if(url) {
      url = url.replace(/\/$/, "")
    }
    getFaviconPath(url, function(err, path, buffer) {
      if(err) { return callback(err); }

      if(path && buffer) { 
        return callback(null, path, buffer); 
      }
      getFaviconLink(url, function(err, path, buffer) {
        if(err) { return callback(err); }

        if(path && buffer) {
          return callback(null, path, buffer); 
        }
        callback();
      });
    });
  });
};

// 获取Favicon.ico
function getFaviconPath(domain, callback) {
  callback = callback || function() {};
  if(!domain) {
    return callback(error.DOMAIN_CANNOT_NULL());
  }

  domain = domain + "/favicon.ico";
  request({ url: domain, method: "GET", encoding: null }, 
    function(err, resp, body) {

    if(err) { return callback(error.REQUEST_ERROR()); }

    if(resp && resp.statusCode == 200 && body.length) {
      return callback(null, domain, body);
    }
    callback();
  });
};

// 获取Link rel=icon的地址
function getFaviconLink(domain, callback) {
  callback = callback || function() {};
  if(!domain) { return callback(error.DOMAIN_CANNOT_NULL()); }

  request.get(domain, function(err, result, body) {
    if(err) { return callback(error.REQUEST_ERROR(err)); }

    var favicon = $(body).find("link[rel*='icon']").attr("href");
    var path = /^http/.test(favicon) ? favicon : (domain + favicon);
    favicon ? request({ 
      url: path, 
      method: "GET", 
      encoding: null 
    }, function(err, resp, body) {
      if(err) { return callback(error.REQUEST_ERROR()); }
      
      if(resp && resp.statusCode == 200 && body.length) {
        return callback(null, path, body);
      }
      callback();
    }) : callback();
  });
};

// 追踪30X的最终地址
function followRedirectUrl(url, callback) {
  if(!url) {
    return callback(error.CANNOT_GET_ICON());
  }
  request.get(url, {
    followRedirect: false
  }, function(err, resp) {
    if(err) {
      return callback(error.REQUEST_ERROR(err));
    }
    if(resp && resp.statusCode > 300 && resp.statusCode < 400 
        && resp.headers && resp.headers.location) {
      followRedirectUrl(resp.headers.location, callback);
    }else {
      var urlobj = urlParser.parse(url);
      var path = urlobj.protocol + "//" + urlobj.host + urlobj.pathname;
      callback(null, path);
    }
  });
};
@@ -692,24 +692,25 @@
 , %22%22)%0A    %7D%0A
+%0A
     getFavic
@@ -711,20 +711,20 @@
 tFavicon
-Path
+Link
 (url, fu
@@ -818,17 +818,16 @@
 uffer) %7B
- 
 %0A       
@@ -869,24 +869,25 @@
 ); %0A      %7D%0A
+%0A
       getFav
@@ -882,36 +882,36 @@
       getFavicon
-Link
+Path
 (url, function(e
@@ -993,32 +993,33 @@
 ath && buffer) %7B
+ 
 %0A          retur
@@ -1057,24 +1057,33 @@
  %0A        %7D%0A
+        %0A
         call
@@ -1086,24 +1086,33 @@
 callback();%0A
+        %0A
       %7D);%0A  
@@ -1109,24 +1109,25 @@
     %7D);%0A
+%0A
     %7D);%0A
   %7D);%0A%7D;
@@ -1118,16 +1118,17 @@
     %7D);%0A
+%0A
   %7D);%0A%7D;

change logic