'use strict';

// Note: we make sure that oauth3 loads first just so that we know the PromiseA
// implementation exists as an angular-style promise before any of the modules
// (all of which use promises) are instantiated


//
// DaplieApiStorage / CannedStorage
//
angular
  .module('daplie.storage', ['oauth3'])
  .service('DaplieApiStorage', [function DaplieApiStorage() {

    console.log('DEBUG DaplieApiStorage');
    return window.CannedStorage.create({
      namespace: 'com.daplie'
    });
  }]);


//
// DaplieApiConfig / Oauth3Config
//
angular
  .module('daplie.config', ['daplie.storage'])
  .service('DaplieApiConfig', [
    '$window'
  , 'DaplieApiStorage'
  , function DaplieApiConfig($window, DaplieApiStorage) {

    console.log('DEBUG DaplieApiConfig');
    return window.Oauth3Config.create({
      defaults: {
        libPrefix: 'ng'
        // TODO this should be grabbed from oauth3.html?action=directives
                      // i.e. https://daplie.com/connect
      , providerUri: 'https://' + window.location.host + window.location.pathname
      , apiBaseUri: 'https://oauth3.org'
      , devProviderUri: 'https://'  + window.location.host + window.location.pathname
      , devApiBaseUri: 'https://oauth3.org'
      , appId: null
      , appUri: window.location.protocol + '//' + window.location.host + window.location.pathname
        // TODO fix this
      , apiPrefix: '/api/org.oauth3.provider'
      //, apiPrefix: '/api/org.oauth3.credentials'
        //< not used yet
      //, credentialsPrefix: '/api/org.oauth3.credentials'
      , consumerPrefix: '/api/org.oauth3.consumer'
      , providerPrefix: '/api/org.oauth3.provider'
        //>
      , refreshWait: (15 * 60 * 1000)
      , uselessWait: Infinity // (30 * 24 * 60 * 60 * 1000)
      // note: host includes 'port' when port is non-80 / non-443
      , invokeLogin: function () {
          window.alert("override `DaplieApiConfig.invokeLogin` with a function that shows a login dialog,"
            + " calls DaplieApiSession.login on click, and returns a promise in that chain."
            + " TODO document on website");
        }
      }
    , storage: DaplieApiStorage
    });
  }]);


//
// DaplieApiCache / JohnnyCache
//
angular
  .module('daplie.cache', ['oauth3', 'daplie.storage'])
  .service('DaplieApiCache', [
    'DaplieApiConfig'
  , 'DaplieApiStorage'
  , function DaplieApiCache(DaplieApiConfig, DaplieApiStorage) {

    // TODO maybe the refreshWait and uselessWait should be here directly
    console.log('DEBUG DaplieApiCache');
    return window.JohnnyCache.create({
      storage: DaplieApiStorage
    , config: DaplieApiConfig
    });
  }]);


//
// DaplieApiSession / TherapySession
//
angular
  .module('daplie.session', ['oauth3', 'daplie.cache', 'daplie.storage', 'daplie.config'])
  .service('DaplieApiSession', [
    '$window'
  , '$timeout'
  , '$q'
  , '$http'
  , 'DaplieApiConfig'
  , 'DaplieApiStorage'
  , 'DaplieApiCache'
  , 'Oauth3'
  , function DaplieApiSession($window, $timeout, $q, $http
      , DaplieApiConfig, DaplieApiStorage, DaplieApiCache/*, Oauth3*/) {

    console.log('DEBUG DaplieApiSession');
    return window.TherapySession.create({
      namespace: 'com.daplie'
    , sessionKey: 'session'
    , cache: DaplieApiCache
    , config: DaplieApiConfig
    , usernameMinLength: 4
    , secretMinLength: 16
    , invokeLogin: null // fallthru to config.invokeLogin
    });
  }]);


//
// DaplieApiRequest
//
angular
  .module('daplie.api', ['daplie.cache', 'daplie.config'])
  .service('DaplieApiRequest', [
    '$window'
  , '$timeout'
  , '$q'
  , '$http'
  , 'DaplieApiConfig'
  , 'DaplieApiCache'
  , 'DaplieApiSession'
  , function DaplieApiRequest($window, $timeout, $q, $http, DaplieApiConfig, DaplieApiCache, DaplieApiSession) {

    console.log('DEBUG DaplieApiRequest');
    return window.DaplieApi.create({
      config: DaplieApiConfig
    , cache: DaplieApiCache
    , session: DaplieApiSession
    });
  }]);


//
// Daplie
//
angular
  .module('daplie', ['oauth3', 'daplie.api', 'daplie.session', 'daplie.cache', 'daplie.storage', 'daplie.config'])
  .service('DaplieApi', [
    '$window', 'DaplieApiStorage', 'DaplieApiCache', 'DaplieApiSession', 'DaplieApiRequest', 'DaplieApiConfig'
  , function ($window, DaplieApiStorage, DaplieApiCache, DaplieApiSession, DaplieApiRequest, DaplieApiConfig) {

    var ngDaplie = $window.ngDaplie = {};
    ngDaplie.storage = DaplieApiStorage;
    ngDaplie.cache = DaplieApiCache;
    ngDaplie.session = DaplieApiSession;
    ngDaplie.request = DaplieApiRequest;
    ngDaplie.config = DaplieApiConfig;
    //ngDaplie.init = ngDaplie.config.init;
    ngDaplie.init = function (opts) {
      console.log('DEBUG init config');
      console.log(opts);
      return ngDaplie.config.init(opts).then(function (config) {
        return ngDaplie.cache.init().then(function () {
          console.log('DEBUG init complete');
          console.log(config);
          return config;
        });
      });
    };

    window.Daplie = ngDaplie;
    return ngDaplie;
  }]);
