/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var _ = require('lodash');
var fse = require('fs-extra');
var git = require('./gitutil');
var blank = {};
var SYSREPO = '_sys';



/**
 * maintains system repository conaining system meta information
 * maintains system commit log and history using nodegit
 * uses master branch only
 * need to be able to create a new repo on demand - for new system definition
 */
module.exports = function(options) {

  var _systems;


  /**
   * ensures that the system repository is in place, creates it if doesn't exist
   */
  var boot = function(cb) {
    if (fse.existsSync(options.systemsRoot + '/' + SYSREPO + '/systems.json')) {
      fse.readFile(options.systemsRoot + '/' + SYSREPO + '/systems.json', 'utf8', function(err, data) {
        _systems = JSON.parse(data);
        cb(err);
      });
    }
    else {
      fse.mkdirpSync(options.systemsRoot + '/' + SYSREPO);
      fse.writeFileSync(options.systemsRoot + '/' + SYSREPO + '/systems.json', JSON.stringify(blank, null, 2), 'utf8');
      git.createRepository(options.systemsRoot + '/' + SYSREPO, ['systems.json'], 'system', 'system@nfd.com', function(err) {
        _systems = blank;
        cb(err);
      });
    }
  };



  /**
   * register a system
   */
  var register = function(user, namespace, name, repoName, repoPath, systemId, cb) {
    if (!_systems[systemId]) {
      _systems[systemId] = { name: name, namespace: namespace, repoName: repoName, repoPath: repoPath };
      fse.writeFileSync(options.systemsRoot + '/' + SYSREPO + '/systems.json', JSON.stringify(_systems, null, 2), 'utf8');
      git.commit(options.systemsRoot + '/' + SYSREPO, 'registered system: ' + repoPath, user.name, user.email, cb);
    }
    else {
      cb(null);
    }
  };



  /**
   * returns a repository path from a system id
   */
  var repoPath = function(systemId) {
    return _systems[systemId].repoPath;
  };



  var repoId = function(repoName) {
    var systemId = _.find(_.keys(_systems), function(systemId) { return _systems[systemId].repoName === repoName; });
    return systemId;
  };



  var listSystems = function() {
    var result = [];
    _.each(_.keys(_systems), function(system) {
      result.push({name: _systems[system].repoName, id: system});
    });
    return result;
  };



  /**
   * convert identifier into full system guid using:
   * 1) exact match on key
   * 2) partial match on key
   * 3) partial match on name
   */
  var findSystem = function(identifier) {
    var re = new RegExp('^' + identifier + '.*', ['i']);
    var systemId;

    systemId = _.find(_.keys(_systems), function(system) { return system === identifier; });

    if (!systemId) {
      systemId = _.find(_.keys(_systems), function(system) { return re.test(system); });
    }

    if (!systemId) {
      systemId = _.find(_.keys(_systems), function(system) { return re.test(_systems[system].repoName); });
    }

    return systemId;
  };



  var systemExists = function(namespace, name) {
    var system = _.find(_systems, function(system) { return system.namespace === namespace && system.name === name; });
    return fse.existsSync(system.repoPath + '/system.json');
  };



  return {
    boot: boot,
    register: register,
    repoPath: repoPath,
    repoId: repoId,
    listSystems: listSystems,
    findSystem: findSystem,
    systemExists: systemExists
  };
};


@@ -742,16 +742,44 @@
 rict';%0A%0A
+var path = require('path');%0A
 var _ = 
@@ -793,24 +793,24 @@
 ('lodash');%0A
-
 var fse = re
@@ -1321,67 +1321,117 @@
     
-if (fse.existsSync(options.systemsRoot + '/' + SYSREPO +
+var sysRepoRoot = path.join(options.systemsRoot, SYSREPO);%0A    var systemsJsonPath = path.join(sysRepoRoot,
  '
-/
 syst
@@ -1440,26 +1440,23 @@
 s.json')
-) %7B
+;%0A
 %0A    
-  
 fse.read
@@ -1464,61 +1464,23 @@
 ile(
-options.systemsRoot + '/' + SYSREPO + '/systems.json'
+systemsJsonPath
 , 'u
@@ -1517,38 +1517,18 @@
     
-  _systems = JSON.parse(data);
+if (err) %7B
 %0A   
@@ -1536,103 +1536,95 @@
     
-cb
+if 
 (err
-);%0A      %7D);%0A    %7D%0A    else %7B%0A      fse.mkdirpSync(options.systemsRoot + '/' + SYSREPO
+.code !== 'ENOENT') %7B return cb(err); %7D%0A%0A        fse.mkdirpSync(sysRepoRoot
 );%0A
+  
     
@@ -1647,61 +1647,23 @@
 ync(
-options.systemsRoot + '/' + SYSREPO + '/systems.json'
+systemsJsonPath
 , JS
@@ -1703,24 +1703,33 @@
 f8');%0A      
+  return 
 git.createRe
@@ -1741,43 +1741,19 @@
 ory(
-options.systemsRoot + '/' + SYSREPO
+sysRepoRoot
 , %5B'
@@ -1804,24 +1804,25 @@
 function(err
+_
 ) %7B%0A        
@@ -1817,24 +1817,26 @@
 ) %7B%0A        
+  
 _systems = b
@@ -1853,17 +1853,22 @@
     
+  
 cb(err
+_
 );%0A
+  
     
@@ -1873,25 +1873,83 @@
     %7D);%0A    
-%7D
+  %7D%0A%0A      _systems = JSON.parse(data);%0A      cb();%0A    %7D);
 %0A  %7D;%0A%0A%0A%0A  /

Simplify sysrevMeta boot