/**
 * Initialize the environment
 */

var envs = require('envs');
if (window.env) envs.set(window.env);

/**
 * Module dependencies
 */

var angular = require('angular');
var hyper = require('ng-hyper');
var feature = require('ng-feature');
var logger = require('./lib/logger');
var hyperagent = require('hyperagent');
var token = require('access-token');
var each = require('each');
var featureUI = require('feature-ui');

/**
 * Expose creating an app
 */

exports = module.exports = function(mod, deps) {
  if (!deps) return angular.module(mod);
  deps.push(hyper.name);
  deps.push(feature.name);
  var app = angular.module(mod, deps);
  app.name = mod;
  return app;
};

/**
 * Start an app with options
 */

exports.run = function(app, options, loadPartial) {

  // initialize the logger
  var log = window.metric = logger(app.name, {
    collector: options.collector || envs('SYSLOG_COLLECTOR'),
    context: options.context || {}
  });

  // initialize the hyperagent client
  hyperagent.set(token.auth());
  hyperagent.profile = log.profile.bind(log);

  // TODO initialize in-progress
  // TODO initialize subscriptions

  // set the default routes
  var routes = options.routes || {'/': 'index'};

  // initialize the routes
  loadPartial = options.loader || loadPartial;
  var routeConfig = {};
  each(routes, function(path, opts) {
    if (typeof opts === 'string') opts = {templateUrl: opts, _route: opts};
    // load the template
    if (loadPartial && opts.templateUrl) opts.templateUrl = loadPartial(opts.templateUrl);

    routeConfig[path] = opts;
  });

  app.config([
    '$routeProvider',
    '$locationProvider',

    function($routeProvider, $locationProvider) {
      each(routeConfig, function(path, opts) {
        // Handle a catch all here
        if (path === '_') return $routeProvider.otherwise(opts);

        $routeProvider.when(path, opts);
      });
      $locationProvider.html5Mode(true).hashPrefix('!');
    }
  ]);

  app.run([
    '$rootScope',
    '$location',

    function($rootScope, $location) {
      var done;

      $rootScope.$on('$routeChangeStart', function() {
        done = log.profile('route_time');
      });

      $rootScope.$on('$routeChangeSuccess', function(currentRoute, conf) {
        if (options.analytics) analytics.pageview();
        if (currentRoute.title) $rootScope.title = currentRoute.title;
        if (conf.$$route._route) $rootScope._route = conf.$$route._route;
        done({path: $location.path()});
      });
    }
  ]);

  /**
   * Show the feature UI
   */

  setTimeout(function() {
    featureUI(options.feature);
  }, 0);
}

/**
 * Initialize the environment
 */

var envs = require('envs');
if (window.env) envs.set(window.env);

/**
 * Module dependencies
 */

var angular = require('angular');
var hyper = require('ng-hyper');
var feature = require('ng-feature');
var logger = require('./lib/logger');
var hyperagent = require('hyperagent');
var token = require('access-token');
var each = require('each');
var featureUI = require('feature-ui');

/**
 * Expose creating an app
 */

exports = module.exports = function(mod, deps) {
  if (!deps) return angular.module(mod);
  deps.push(hyper.name);
  deps.push(feature.name);
  var app = angular.module(mod, deps);
  app.name = mod;
  return app;
};

/**
 * Start an app with options
 */

exports.run = function(app, options, loadPartial) {

  // initialize the logger
  var log = window.metric = logger(app.name, {
    collector: options.collector || envs('SYSLOG_COLLECTOR'),
    context: options.context || {}
  });

  // initialize the hyperagent client
  hyperagent.set(token.auth());
  hyperagent.profile = log.profile.bind(log);

  // TODO initialize in-progress
  // TODO initialize subscriptions

  // set the default routes
  var routes = options.routes || {'/': 'index'};

  // initialize the routes
  loadPartial = options.loader || loadPartial;
  var routeConfig = {};
  each(routes, function(path, opts) {
    if (typeof opts === 'string') opts = {templateUrl: opts, _route: opts};
    // load the template
    if (loadPartial && opts.templateUrl) opts.templateUrl = loadPartial(opts.templateUrl);

    routeConfig[path] = opts;
  });

  app.config([
    '$routeProvider',
    '$locationProvider',

    function($routeProvider, $locationProvider) {
      each(routeConfig, function(path, opts) {
        // Handle a catch all here
        if (path === '_') return $routeProvider.otherwise(opts);

        $routeProvider.when(path, opts);
      });
      $locationProvider.html5Mode(true).hashPrefix('!');
    }
  ]);

  app.run([
    '$rootScope',
    '$location',

    function($rootScope, $location) {
      var done;

      $rootScope.$on('$routeChangeStart', function() {
        done = log.profile('route_time');
      });

      $rootScope.$on('$routeChangeSuccess', function(currentRoute, conf) {
        if (options.analytics) analytics.pageview();
        if (currentRoute.title) $rootScope.title = currentRoute.title;
        if (conf.$$route._route) $rootScope._route = conf.$$route._route;
        done({path: $location.path()});
      });
    }
  ]);

  /**
   * Show the feature UI
   */

  setTimeout(function() {
    featureUI(options.feature);
    if (!window.performance && !window.performance.timing) return;
    var t = performance.timing;
    var timing = {
      'measure#performance.connect': t.connectEnd - t.connectStart + 'ms',
      'measure#performance.domain': t.domainLookupEnd - t.domainLookupStart + 'ms',
      'measure#performance.response': t.responseEnd - t.requestStart + 'ms',
      'measure#performance.dom': t.domComplete - t.domLoading + 'ms'
    };
    log(timing);
  }, 0);
}

add performance logging