const BASE_URL = "https://www.transifex.com/api/2/project/";
const API_URL = "https://www.transifex.com/api/2/";

var request = require("request"),
    env = require("./config.js"),
    _ = require("lodash"),
    authHeader = "Basic " + new Buffer(env.get("TRANSIFEX-AUTH")).toString("base64"),
    projectUrl = BASE_URL + env.get("TRANSIFEX-PROJECT"),
    slugs = [],
    languages = [],
    languagesInfo = [],
    projectObj = {};

// API URLs for Transifex
var languagesAPIUrl = projectUrl + "/languages/",
    languageCodeUrl = BASE_URL + "/language/",
    resourceAPIUrl = projectUrl + "/resources/",
    projectResourceUrl = projectUrl + "/resource/",
    projectDetailsAPIUrl = projectUrl + "/?details";
    languageInfoURL = API_URL + "language/"

// request the project details based on the url provided
function projectRequest (url, callback) {
  request.get({
    url: url,
    headers: {"Authorization": authHeader}
  }, function(error, response, body) {
    if (error) {
      return callback(error);
    }
    if (response.statusCode !== 200) {
      return callback(Error(url + " returned " + response.statusCode));
    }
    callback(null, body);
  });
};

function projectDetails(callback) {
  projectRequest(projectDetailsAPIUrl, function(err, projectData){
    if (err) {
      return callback(err);
    }
    try {
      projectData = JSON.parse(projectData);
    } catch (e) {
      return callback(e);
    }
    languages = projectData.teams;
    projectData.resources.forEach(function(data) {
      slugs.push(data.slug);
    });
    var wait = languages.length;
    languages.forEach(function(language) {
      var url = languageInfoURL + language + "/";
      projectRequest(url, function(err, data){
        if (err) {
          return callback(err);
        }
        try {
          data = JSON.parse(data);
          languagesInfo.push({
            locale: data.code,
            name: data.name
          });
        } catch (e) {
          return callback(e);
        }
        wait--;
        if (wait === 0) {
          projectObj.languages = languagesInfo;
          projectObj.slugs = slugs;
          callback(null, projectObj)
        }
      });
    });
  });
};

function projectStats(callback) {
  projectDetails(function (error, data) {
    if (error) {
      return callback(error);
    }
    var wait = slugs.length,
        finalDetails = {};
    data.slugs.forEach(function (slug) {
      var details = {},
          url = projectResourceUrl + slug + "/stats/";
      projectRequest(url, function(err, projectData){
        if (err) {
          return callback(err);
        }
        try {
          projectData = JSON.parse(projectData);
          details[slug] = projectData;
        } catch (e) {
          return callback(e);
        }
        _.extend(finalDetails, details)
        wait--;
        if ( wait === 0 ) {
          callback(null, finalDetails);
        }
      });
    });
  });
};

// return the number of contributors in each role and the total number
function getNumberOfContributors( callback ) {
  var contributorsDetails = [],
      numOfTranslators = 0,
      numOfReviewers = 0,
      numOfCoordinators = 0,
      totalNum = 0;

  projectRequest(languagesAPIUrl, function(err, projectDetails){
    if (err) {
      return callback(err);
    }
    try {
      projectDetails = JSON.parse(projectDetails);
    } catch (e) {
      return callback(e);
    }
    projectDetails.forEach(function(data) {
      numOfTranslators += data.translators.length;
      numOfReviewers += data.reviewers.length;
      numOfCoordinators += data.coordinators.length;
    });
    contributorsDetails.push({
      "component": "Contributors",
      "count": numOfTranslators + numOfReviewers + numOfCoordinators
    });
    contributorsDetails.push( {
      "component": "Translators",
      "count": numOfTranslators
    });
    contributorsDetails.push( {
      "component": "Reviewers",
      "count": numOfReviewers
    });
    contributorsDetails.push( {
      "component": "Coordinators",
      "count": numOfCoordinators
    });
    callback( null, contributorsDetails );
  });
};

function getAllLanguages(callback) {
  projectDetails(function (error, data) {
    if (error) {
      return callback(error);
    }
    callback(null, data.languages);
  });
};

function componentStats(component, callback) {
  var url = projectResourceUrl + component + "/stats/";
  projectRequest(url, function(err, data){
    if (err) {
      return callback(err);
    }
    try {
      data = JSON.parse(data);
    } catch (e) {
      return callback(e);
    }
    callback(null, data);
  });
};

function getLangCompStats(component, lang, callback) {
  projectDetails(function(error, data) {
    if (error) {
      return callback(error);
    }
    var arrOfLocale = [];
    data.languages.forEach(function(langCode) {
      arrOfLocale.push(langCode.locale);
    });
    if (data.slugs.indexOf(component) === -1) {
      return callback(Error("Error: Unknown component's name"));
    } else if (arrOfLocale.indexOf(lang) === -1) {
      return callback(Error("Error: Unknown locale's name"));
    }
    componentStats(component, function(error, componentData) {
      if (error) {
        return callback(error);
      }
      callback(null, componentData[lang])
    })
  });
};

module.exports.numberOfContributors = getNumberOfContributors;
module.exports.projectStats = projectStats;
module.exports.getAllLanguages = getAllLanguages;
module.exports.componentStats = componentStats;
module.exports.getLangCompStats = getLangCompStats;

@@ -5149,63 +5149,121 @@
     
-componentStats(component, function(error, componentD
+var url = projectResourceUrl + component + %22/stats/%22 + lang + %22/%22;%0A    projectRequest(url, function(err, langSt
 at
-a
 ) %7B%0A
@@ -5267,34 +5267,32 @@
  %7B%0A      if (err
-or
 ) %7B%0A        retu
@@ -5302,26 +5302,133 @@
 callback(err
-or
+);%0A      %7D%0A      try %7B%0A        langStat = JSON.parse(langStat);%0A      %7D catch (e) %7B%0A        return callback(e
 );%0A      %7D%0A 
@@ -5451,35 +5451,26 @@
 ll, 
-componentData%5Blang%5D)
+langStat);
 %0A    %7D)
+;
 %0A  %7D

Refactor getLangCompStats function