import minimist from 'minimist';
import path from 'path';
import Q from 'q';
import fs from 'fs';
import assrt from 'assert';
import { getLogger } from './logger';

let logger;

const ASSIGNMENT_CACHE_FILE = ".assignmentcache.json";

function validateConfig (config) {
  try {
    assrt.ok(config.repos);
    assrt(config.repos.length > 0);
    for (let repo of config.repos) {
      assrt.ok(repo.user);
      assrt.ok(repo.repo);
      assrt.ok(repo.triagers);
      assrt(repo.triagers.length >= 0);
      if (repo.autoLabels) {
        assrt(repo.autoLabels instanceof Array);
      }
      if (repo.validLabels) {
        assrt(repo.validLabels instanceof Array);
      }
    }
    assrt.ok(process.env.TRIAGER_TOKEN);
  } catch (e) {
    console.log(e.stack);
    throw new Error("Invalid config: " + e.message);
  }
}

async function getCachedAssignments (config) {
  let cacheFile = path.resolve(__dirname, "..", "..",
      ASSIGNMENT_CACHE_FILE);
  let cacheData = null;
  let exists = true;
  try {
    await Q.nfcall(fs.stat, cacheFile);
  } catch (e) {
    exists = false;
  }
  if (exists) {
    if (config.nocache) {
      logger.info("Assignment cache exists, but ignoring it");
    } else {
      logger.info("Assignment cache exists, loading it");
      cacheData = await Q.nfcall(fs.readFile, cacheFile);
      logger.debug("Cached assignments: " + cacheData.toString('utf8'));
      cacheData = JSON.parse(cacheData.toString('utf8'));
    }
  } else {
    logger.info("No assignment cache present");
  }
  return cacheData;
}

async function configure (loadCachedAssignments = true) {
  let args = minimist(process.argv.slice(2));
  logger = getLogger();
  if (!args.config) {
    throw new Error("Config file is required");
  }
  args.repoConfig = require(args.config);
  validateConfig(args.repoConfig);
  args.port = args.port || 4567;
  args.host = args.host || '0.0.0.0';
  if (loadCachedAssignments) {
    args.cachedAssignments = await getCachedAssignments(args);
  }
  return args;
}

export { configure, ASSIGNMENT_CACHE_FILE };

@@ -295,16 +295,59 @@
 ig.repos
+, %60config.repos was not valid in $%7Bconfig%7D%60
 );%0A    a
@@ -442,106 +442,267 @@
 user
-);%0A      assrt.ok(repo.repo);%0A      assrt.ok(repo.triagers);%0A      assrt(repo.triagers.length %3E= 0
+, %60repo.user was not set for $%7Brepo%7D%60);%0A      assrt.ok(repo.repo, %60repo.repo was not set for $%7Brepo%7D%60);%0A      assrt.ok(repo.triagers, %60repo.triagers was not set for $%7Brepo%7D%60);%0A      assrt(repo.triagers.length %3E= 0, %60must have at least one triager for $%7Brepo%7D%60
 );%0A 
@@ -767,32 +767,80 @@
 instanceof Array
+, %60repo.autoLabels must be an array for $%7Brepo%7D%60
 );%0A      %7D%0A     
@@ -911,16 +911,65 @@
 of Array
+, %60repo.validLabels must be an array for $%7Brepo%7D%60
 );%0A     
@@ -1015,16 +1015,64 @@
 ER_TOKEN
+, 'TRIAGER_TOKEN must be set in the environment'
 );%0A  %7D c

make validations return informative errors