#!/usr/bin/env node
var tsp = require("typescript-parser");
var fs = require('fs');
var path = require('path');
var ts = require("typescript");

var parser = new tsp.TypescriptParser();
var excludedDirs = [
  path.resolve(__dirname, "modules", "generated")
];

var walkFileTree = function (dir, action) {
  if (typeof action !== "function") {
    return;
  }

  fs.readdirSync(dir).forEach(function (file) {
    var filePath = dir + path.sep + file;
    var stat = fs.statSync(filePath);
    var extension = ".ts";
    if (stat && stat.isDirectory() && excludedDirs.indexOf(filePath) === -1) {
      walkFileTree(filePath, action);
    }
    else if (filePath.indexOf(extension, filePath.length - extension.length) !== -1) {
      action(null, filePath);
    }
  });
};

var dateInLong = Date.now();
var arr = [];

function parseTsMeta(file,childModule) {
  var content = fs.readFileSync(file).toString();
  var jsonStructure = parser.parseTypescript(ts.createSourceFile(
          file,
          content,
          ts.ScriptTarget.Latest,
          true,
          ts.ScriptKind.TS
      ),
      '/');

  if (childModule) {
    let moduleRelativePath = path.relative(path.resolve(__dirname, "modules"), file);
    let pathElements = moduleRelativePath.split(path.sep);
    jsonStructure['moduleName'] = pathElements.shift();
    pathElements.shift(); //remove src folder
    pathElements.shift(); //remove lib folder
    jsonStructure['packageName'] = pathElements.join(path.sep);
  }else {
    jsonStructure['packageName'] = path.relative(path.resolve(__dirname, "src", "ts"), jsonStructure['filePath']);
  }
  jsonStructure['imports'].forEach( function (val) {

    if (val.libraryName.startsWith(".")) {
      val['libraryName'] = path.resolve(path.dirname(jsonStructure['filePath']), val['libraryName']);

      if (childModule) {
        // let subPath = "modules" + path.sep + jsonStructure['moduleName'] + path.sep + "src" + path.sep + "lib";
        val['libraryName'] = path.relative(path.resolve(__dirname, "modules", jsonStructure['moduleName'], "src", "lib"), val['libraryName']);
      }
      else {
        val['libraryName'] = path.relative(path.resolve(__dirname, "src", "ts"), val['libraryName']);
      }

      val['libraryName'] = path.dirname(val['libraryName']).split(path.sep).join(".");
    }
  });
  delete jsonStructure['filePath'];
  jsonStructure['packageName'] = path.dirname(jsonStructure['packageName']).split(path.sep).join( ".");
  arr.push(jsonStructure);
}


var basePath = path.resolve(__dirname, "src", "ts");

walkFileTree(basePath, function (err, file) {
  parseTsMeta(file, false);
});

walkFileTree(path.resolve(__dirname, "modules"), function (err, file) {
  parseTsMeta(file,true);
});
var cache = [];

fs.writeFileSync("./../.studio/typescript.metadata.json",
    JSON.stringify(arr, function (key, value) {
      if (typeof value === 'object' && value !== null) {
        if (cache.indexOf(value) !== -1) {
          // Circular reference found, discard key
          return;
        }
        // Store value in our collection
        cache.push(value);
      }
      return value;
    }));

cache = null;
console.log("typescript parse time = " + (Date.now() - dateInLong));
