/* !
  update.js

  run $ npm install
  run $ node unpdate.js

  Downloads latest version of microformat-shiv and it tests form github repo
  Files downloaded:
  * microformat-shiv.js (note: modern version)
  * lib
  * test/interface-tests
  * test/module-tests
  * test/standards-tests
  * test/static

  Copyright (C) 2015 Glenn Jones. All Rights Reserved.
  MIT License: https://raw.github.com/glennjones/microformat-shiv/master/license.txt
*/

// configuration
var deployDir = "../";
var exportedSymbol = 'try {\n    // mozilla jsm support\n    Components.utils.importGlobalProperties(["URL"]);\n} catch(e) {}\nthis.EXPORTED_SYMBOLS = [\'Microformats\'];';



var path     = require("path"),
    request  = require("request"),
    fs       = require("fs-extra"),
    download = require("download-github-repo");


var repo = "glennjones/microformat-shiv",
    tempDir = path.resolve(__dirname, "temp-repo"),
    deployDirResolved = path.resolve(__dirname, deployDir),
    pathList = [
      ["/modern/microformat-shiv-modern.js", "/microformat-shiv.js"],
      ["/lib", "/test/lib"],
      ["/test/interface-tests", "/test/interface-tests"],
      ["/test/module-tests", "/test/module-tests"],
      ["/test/standards-tests", "/test/standards-tests"],
      ["/test/static", "/test/static"]
    ];



getLastBuildState( repo, function( err, buildState) {
  if (buildState) {
    console.log("last build state:", buildState);

    if (buildState === "passed") {

      console.log("downloading git repo", repo);
      getLastCommitDate( repo, function( err, date) {
      if (date) {
        console.log( "last commit:", new Date(date).toString() );
      }
      });
      updateFromRepo();

    } else {
      console.log("not updating because of build state is failing please contact Glenn Jones glennjones@gmail.com");
    }

    } else {
      console.log("could not get build state from travis-ci:", err);
  }
});


/**
 * updates from directories and files from repo
 *
 */
function updateFromRepo() {
  download(repo, tempDir, function(err, data) {

    // the err and data from download-github-repo give false negatives
    if ( fs.existsSync( tempDir ) ) {

      var version = getRepoVersion();
      removeCurrentFiles( pathList, deployDirResolved );
      addNewFiles( pathList, deployDirResolved );
      fs.removeSync(tempDir);

      // changes files for firefox
      replaceInFile("/test/module-tests/index.html", /..\/..\/lib\//g, "../lib/" );
      addExportedSymbol( "/microformat-shiv.js" );

      console.log("microformat-shiv is now uptodate to v" + version);

    } else {
      console.log("error getting repo", err);
    }

  });
}


/**
 * removes old version of delpoyed directories and files
 *
 * @param  {Array} pathList
 * @param  {String} deployDirResolved
 */
function removeCurrentFiles( pathList, deployDirResolved ) {
  pathList.forEach( function( path ) {
    console.log("removed:", deployDirResolved + path[1]);
    fs.removeSync(deployDirResolved + path[1]);
  });
}


/**
 * copies over required directories and files into deployed path
 *
 * @param  {Array} pathList
 * @param  {String} deployDirResolved
 */
function addNewFiles( pathList, deployDirResolved ) {
  pathList.forEach( function( path ) {
    console.log("added:", deployDirResolved + path[1]);
    fs.copySync(tempDir + path[0], deployDirResolved + path[1]);
  });

}


/**
 * gets the repo version number
 *
 * @return {String}
 */
function getRepoVersion() {
  var pack = fs.readFileSync(path.resolve(tempDir, "package.json"), {encoding: "utf8"});
  if (pack) {
    pack = JSON.parse(pack)
    if (pack && pack.version) {
      return pack.version;
    }
  }
  return "";
}


/**
 * get the last commit date from github repo
 *
 * @param  {String} repo
 * @param  {Function} callback
 */
function getLastCommitDate( repo, callback ) {

  var options = {
    url: "https://api.github.com/repos/" + repo + "/commits?per_page=1",
    headers: {
      "User-Agent": "request"
    }
  };

  request(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {
      var date = null,
      json = JSON.parse(body);
      if (json && json.length && json[0].commit && json[0].commit.author ) {
        date = json[0].commit.author.date;
      }
      callback(null, date);
    } else {
      console.log(error, response, body);
      callback("fail to get last commit date", null);
    }
  });
}


/**
 * get the last build state from travis-ci
 *
 * @param  {String} repo
 * @param  {Function} callback
 */
function getLastBuildState( repo, callback ) {

  var options = {
    url: "https://api.travis-ci.org/repos/" + repo,
    headers: {
      "User-Agent": "request",
      "Accept": "application/vnd.travis-ci.2+json"
    }
  };

  request(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {
      var buildState = null,
      json = JSON.parse(body);
      if (json && json.repo && json.repo.last_build_state ) {
        buildState = json.repo.last_build_state;
      }
      callback(null, buildState);
    } else {
      console.log(error, response, body);
      callback("fail to get last build state", null);
    }
  });
}


/**
 * adds exported symbol to microformat-shiv.js file
 *
 * @param  {String} path
 * @param  {String} content
 */
function addExportedSymbol( path ) {
  if (path === "/microformat-shiv.js") {
    fs.appendFileSync(deployDirResolved + "/microformat-shiv.js", "\r\n" + exportedSymbol + "\r\n");
    console.log("appended exported symbol to microformat-shiv.js");
  }
}


/**
 * adds exported symbol to microformat-shiv.js file
 *
 * @param  {String} path
 * @param  {String} content
 */
function replaceInFile( path, findStr, replaceStr ) {
  readFile(deployDirResolved + path, function(err, fileStr) {
    if (fileStr) {
      fileStr = fileStr.replace(findStr, replaceStr)
      writeFile(deployDirResolved + path, fileStr);
      console.log("replaced " + findStr + " with " + replaceStr + " in " + path);
    } else {
      console.log("error replaced strings in " + path);
    }
  })
}


/**
 * write a file
 *
 * @param  {String} path
 * @param  {String} content
 */
function writeFile(path, content) {
  fs.writeFile(path, content, "utf8", function(err) {
    if (err) {
      console.log(err);
    } else {
      console.log("The file: " + path + " was saved");
    }
  });
}


/**
 * read a file
 *
 * @param  {String} path
 * @param  {Function} callback
 */
function readFile(path, callback) {
  fs.readFile(path, "utf8", callback);
}
