// Generated by CoffeeScript 1.9.2
(function() {
  var configCache, findPackageJson, findPackageJsonSync, fs, getConfigFromCache, loadExternalConfig, loadJsonAsync, packageJsonCache, parentDir, path, processConfig, storeConfigInCache;

  path = require('path');

  fs = require('fs');

  parentDir = require('./parentDir');

  packageJsonCache = {};

  findPackageJson = function(dirname, done) {
    var answer;
    answer = packageJsonCache[dirname];
    if (answer) {
      return process.nextTick(function() {
        return done(null, answer);
      });
    } else {
      return parentDir.parentDir(dirname, 'package.json', function(err, packageDir) {
        var packageFile;
        if (err) {
          return done(err);
        }
        if (packageDir) {
          packageFile = path.join(packageDir, 'package.json');
        } else {
          packageFile = null;
        }
        packageJsonCache[dirname] = packageFile;
        return done(null, packageFile);
      });
    }
  };

  findPackageJsonSync = function(dirname) {
    var answer, packageDir, packageFile;
    answer = packageJsonCache[dirname];
    if (!answer) {
      packageDir = parentDir.parentDirSync(dirname, 'package.json');
      if (packageDir) {
        packageFile = path.join(packageDir, 'package.json');
      } else {
        packageFile = null;
      }
      packageJsonCache[dirname] = packageFile;
      answer = packageFile;
    }
    return answer;
  };

  configCache = {};

  getConfigFromCache = function(transformName, packageFile) {
    var cacheKey;
    cacheKey = transformName + ":" + packageFile;
    if (configCache[cacheKey] != null) {
      return configCache[cacheKey];
    } else {
      return null;
    }
  };

  storeConfigInCache = function(transformName, packageFile, configData) {
    var cacheKey, cachedConfigData, key, value;
    cacheKey = transformName + ":" + packageFile;
    cachedConfigData = {};
    for (key in configData) {
      value = configData[key];
      cachedConfigData[key] = value;
    }
    cachedConfigData.cached = true;
    return configCache[cacheKey] = cachedConfigData;
  };

  loadJsonAsync = function(filename, done) {
    return fs.readFile(filename, "utf-8", function(err, content) {
      if (err) {
        return done(err);
      }
      try {
        return done(null, JSON.parse(content));
      } catch (_error) {
        err = _error;
        return done(err);
      }
    });
  };

  loadExternalConfig = function(packageFile, relativeConfigFile) {
    var config, configDir, configFile, packageDir;
    packageDir = path.dirname(packageFile);
    configFile = path.resolve(packageDir, relativeConfigFile);
    configDir = path.dirname(configFile);
    config = require(configFile);
    return {
      config: config,
      configDir: configDir,
      configFile: configFile,
      packageFile: packageFile,
      cached: false
    };
  };

  processConfig = function(transformName, packageFile, config) {
    var configData, configDir, configFile;
    if (typeof config === "string") {
      configData = loadExternalConfig(packageFile, config);
    } else {
      configFile = packageFile;
      configDir = path.dirname(packageFile);
      configData = {
        config: config,
        configDir: configDir,
        configFile: configFile,
        packageFile: packageFile,
        cached: false
      };
    }
    if (configData.config.appliesTo) {
      configData.appliesTo = configData.config.appliesTo;
      delete configData.config.appliesTo;
    }
    storeConfigInCache(transformName, packageFile, configData);
    return configData;
  };

  exports.loadTransformConfig = function(transformName, file, options, done) {
    var dir, findConfig;
    if (done == null) {
      done = options;
      options = {};
    }
    if (options.fromSourceFileDir) {
      dir = path.dirname(file);
    } else {
      dir = process.cwd();
    }
    findConfig = function(dirname) {
      return findPackageJson(dirname, function(err, packageFile) {
        var configData;
        if (err) {
          return done(err);
        }
        if (packageFile == null) {
          return done(null, null);
        } else {
          configData = getConfigFromCache(transformName, packageFile);
          if (configData) {
            return done(null, configData);
          } else {
            return loadJsonAsync(packageFile, function(err, pkg) {
              var config, packageDir, parent;
              if (err) {
                return done(err);
              }
              config = pkg[transformName];
              packageDir = path.dirname(packageFile);
              if (config == null) {
                if (!options.fromSourceFileDir) {
                  return done(null, null);
                } else {
                  parent = path.resolve(packageDir, "..");
                  if (parent === packageDir) {
                    return done(null, null);
                  } else {
                    return findConfig(parent);
                  }
                }
              } else {
                try {
                  configData = processConfig(transformName, packageFile, config);
                  return done(null, configData);
                } catch (_error) {
                  err = _error;
                  return done(err);
                }
              }
            });
          }
        }
      });
    };
    return findConfig(dir);
  };

  exports.loadTransformConfigSync = function(transformName, file, options) {
    var config, configData, dirname, done, packageDir, packageFile, pkg;
    if (options == null) {
      options = {};
    }
    configData = null;
    if (options.fromSourceFileDir) {
      dirname = path.dirname(file);
    } else {
      dirname = process.cwd();
    }
    done = false;
    while (!done) {
      packageFile = findPackageJsonSync(dirname);
      if (packageFile == null) {
        configData = null;
        done = true;
      } else {
        configData = getConfigFromCache(transformName, packageFile);
        if (configData) {
          done = true;
        } else {
          pkg = require(packageFile);
          config = pkg[transformName];
          packageDir = path.dirname(packageFile);
          if (config == null) {
            if (!options.fromSourceFileDir) {
              done = true;
            } else {
              dirname = path.resolve(packageDir, "..");
              if (dirname === packageDir) {
                done = true;
              }
            }
          } else {
            configData = processConfig(transformName, packageFile, config);
            done = true;
          }
        }
      }
    }
    return configData;
  };

  exports.clearConfigCache = function() {
    packageJsonCache = {};
    return configCache = {};
  };

}).call(this);
