/**
 * Load a project.
 * @param {string} projectName - Project name or file path to load.
 * @returns {object} - An apeman project object.
 */
var Project = require('./project'),
    util = require('util'),
    fs = require('fs'),
    path = require('path'),
    findupApemanfile = require('./findup_apemanfile');

exports = module.exports = function (projectName) {
    if (!projectName) {
        projectName = process.cwd();
    }
    var found = exports._find(projectName);
    if (found && fs.statSync(found).isDirectory()) {
        found = findupApemanfile(projectName);
    }
    if (!found) {
        var notFoundMsg = util.format('apeman project not found: %s', projectName);
        throw new Error(notFoundMsg);
    }
    var config = require(found);
    return new Project(config);
};

exports._find = function (projectName) {
    if (!projectName) return null;
    return exports._findupLocal(projectName) ||
        exports._findupCoreApps(projectName) ||
        exports._findFromNodeModule(projectName) ||
        null;
};

exports._findupCoreApps = function (projectName) {
    var coreAppsDir = path.resolve(__dirname, '../core_apps'),
        resolved = path.resolve(coreAppsDir, projectName);
    try {
        return require.resolve(resolved);
    } catch (e) {
        return null;
    }
};


exports._findupLocal = function (dirname) {
    if (fs.existsSync(dirname)) {
        return dirname;
    }
    return findupApemanfile(path.resolve('..', dirname));
};

exports._findFromNodeModule = function (moduleName) {
    try {
        return require.resolve(moduleName);
    } catch (e) {
        //DO nothing.
    }
    var dirnames = process.cwd().split(path.sep);
    while (dirnames.length) {
        var filename = dirnames.concat(['node_modules', moduleName]).join(path.sep);
        if (fs.existsSync(filename)) {
            try {
                return require.resolve(filename);
            } catch (e) {
                //Do nothing.
            }
        }
        dirnames.pop();
    }
    return null;
};