// DecentCMS (c) 2014 Bertrand Le Roy, under MIT. See LICENSE.txt for licensing details.
'use strict';
var path = require('path');
var fs = require('fs');

/**
 * @description
 * A content store that uses JSON files.
 * @param shell
 * @constructor
 */
function FileContentStore(shell) {
  this.shell = shell;
}
FileContentStore.isShellSingleton = true;

FileContentStore.on = {
  'decent.core.load-items': function(shell, payload) {
    var shapeHelper = shell.require('shape');

    var items = payload.items;
    var itemsToFetch = payload.itemsToFetch;
    var callback = payload.callback;

    var count = 0;
    var siteDataRoot = path.join(shell.rootPath, 'data/content');
    var handle = function(id, filePath, data) {
      var item = JSON.parse(data);
      var temp = shapeHelper.temp(item);
      temp.filePath = filePath;
      items[id] = item;
      for(var j = 0; j < itemsToFetch[id].length; j++) {
        itemsToFetch[id](null, item);
      }
      delete itemsToFetch[id];
      if (--count <= 0) {
        callback();
      }
    };
    for (var id in itemsToFetch) {
      count++;
      (function(id) {
        // TODO: support for redirected roots where a folder points at another. This will enable module documentation sub sites.
        var itemFilePath = path.join(siteDataRoot, id, 'index.json');
        fs.readFile(itemFilePath, function(err, data) {
          if (err) {
            console.log('File not found ' + err.name);
            // TODO: handle only file not found, re-throw the rest.
            // Not a folder, maybe a file
            itemFilePath = path.join(siteDataRoot, id);
            fs.readFile(itemFilePath, function(err, data) {
              if (err) {
                for(var j = 0; j < itemsToFetch[id].length; j++) {
                  itemsToFetch[id](err);
                }
                count--;
                return;
              }
              handle(id, itemFilePath, data);
            });
            return;
          }
          handle(id, itemFilePath, data);
        });
      })(id);
    }
  }
};

module.exports = FileContentStore;
@@ -731,37 +731,210 @@
     
-var item = JSON.parse(data);%0A
+// Parse the content item file%0A      var item = JSON.parse(data);%0A      // Prepare the last operations for later.%0A      var finalCallback = function() %7B%0A        // Add the file path to temp meta data%0A  
     
@@ -966,24 +966,26 @@
 temp(item);%0A
+  
       temp.f
@@ -1014,26 +1014,111 @@
     
-items%5Bid%5D = item;%0A
+  // Add to the items list%0A        items%5Bid%5D = item;%0A        // Call all the item-specific callbacks%0A  
     
@@ -1114,32 +1114,33 @@
 acks%0A        for
+ 
 (var j = 0; j %3C 
@@ -1171,32 +1171,34 @@
  j++) %7B%0A        
+  
 itemsToFetch%5Bid%5D
@@ -1207,24 +1207,26 @@
 ull, item);%0A
+  
       %7D%0A    
@@ -1231,33 +1231,148 @@
     
-delete itemsToFetch%5Bid%5D;%0A
+  // Remove from the list of remaining items to fetch%0A        delete itemsToFetch%5Bid%5D;%0A        // If we're done, call the global callback%0A  
     
@@ -1401,16 +1401,18 @@
         
+  
 callback
@@ -1417,25 +1417,733 @@
 ck();%0A      
-%7D
+  %7D%0A      %7D;%0A      // Look for any part that needs to load an additional file.%0A      // Typically, that could be a markdown file for the body.%0A      var count = 0;%0A      for (var partName in item) %7B%0A        if (partName === 'meta' %7C%7C partName === 'temp') continue;%0A        var part = item%5BpartName%5D;%0A        if (part.hasOwnProperty('path')) %7B%0A          count++;%0A          var extraFilePath = path.join(path.dirname(filePath), part.path);%0A          fs.readFile(extraFilePath, function(err, data) %7B%0A            // TODO: handle error%0A            part._data = data.toString();%0A            count--;%0A            if (count %3C= 0) finalCallback();%0A          %7D);%0A        %7D%0A      %7D%0A      if (count %3C= 0) finalCallback();
 %0A    %7D;%0A    
@@ -3018,32 +3018,43 @@
 emFilePath, data
+.toString()
 );%0A            %7D
@@ -3123,24 +3123,35 @@
 lePath, data
+.toString()
 );%0A        %7D

Support in file content store for parts that point at external files. A scenario is a JSON content item file pointing at an external markdown file for its body.