"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var storage_1 = require("../../util/storage");
var util_1 = require("../../util/util");
var api_1 = require("../../api");
var json_api_1 = require("./json-api");
var config_1 = require("../../config");
var Drupal = /** @class */ (function () {
    function Drupal(config, apiService) {
        if (apiService === void 0) { apiService = undefined; }
        this.user = {};
        this.model = {
            // jsonApi
            entities: {},
            collections: {},
            nodes: {},
            views: {},
            menus: {},
            books: {},
            siteParams: {}
        };
        this.saveLocalModel = storage_1.Storage.saveLocalModel;
        this.restoreLocalModel = storage_1.Storage.restoreLocalModel;
        this.cache = false;
        this.routes = {};
        this.version = 'drupal-8';
        this.sites = {};
        // default user = 'services';
        this.defaultAuthHeader = 'Basic c2VydmljZXM6OSs0djJGdm0zMi84Ymtl';
        // standard Promise based api
        this.api = new api_1.Api();
        this.jsonApi = new json_api_1.JsonApi();
        if (apiService) {
            // add Angular Observable api
            this.api = apiService;
        }
        this.model.entities = this.jsonApi.entities;
        this.model.collections = this.jsonApi.collections;
        this.model.nodes = this.jsonApi.nodes;
        this.model.views = this.jsonApi.views;
        if (config) {
            this.config = config;
        }
        else {
            this.config = new config_1.Config();
        }
        this.settings = this.config['_config'];
        // this.settings = this.config['_config']['drupal'];
    }
    Drupal.prototype.init = function (options) {
        this.options = options;
        if (options.version) {
            this.version = options.version;
        }
        this.domain = options.domain;
        this.static = options.static || false;
        this.cache = options.cache || false;
        this.standalone = options.standalone || false;
        this.base_path = options.base_path || '/';
        this.protocol = options.protocol || 'http:';
        this.sites[this.domain] = {};
        this.file_directory_path = options.file_directory_path || 'sites/default/files';
        this.file_directory_path = this.baseUrl + this.file_directory_path;
        this.initApi();
        var promises = [];
        if (util_1.Util.isOnline() && !this.static) {
            // online
            // promises.push(jDrupal.connect());
            promises.push(this.getParams());
            promises.push(this.getLocalStorageCredentials());
            promises.push(this.jsonApi.getResourcesIndex(this.settings.drupal.api.path_prefix, this.config.get('language')));
            promises.push(new Promise(function (resolve, reject) {
                resolve();
            }));
            return Promise.all(promises);
        }
        else {
            // fixme: todo: offline or static
            var self_1 = this;
            return new Promise(function (resolve, reject) {
                // self.restoreLocalModel(self.domain)
                // self.getLocalStorageCredentials().then(() => {
                resolve();
                // })
            });
        }
    };
    Drupal.prototype.initApi = function () {
        this.baseUrl = this.settings.drupal.api.host = this.protocol + '//' + this.domain + this.base_path;
        this.api.init(this.settings.drupal.api);
        this.jsonApi.init(this.settings.drupal.api);
        this.jsonApi.cache = this.cache;
        // todo:
        if (this.config.get('drupal')['hasLanguages'] && this.config.get('language')) {
            //     this.api.baseUrl += this.config.get('language') + '/';
            //     this.jsonApi.baseUrl += this.config.get('language') + '/';
        }
        if (window) {
            // drupal-7
            if (window['Drupal']) {
                if (window['Drupal'].url && window['Drupal'].url.isLocal()) {
                    this.isLocal = true;
                }
                else {
                    this.isLocal = false;
                }
            }
            window['Drupal'] = window['Drupal'] || {};
            window['Drupal'].app_server_model = this.model;
            window['Drupal'].settings = window['Drupal'].settings || {};
            window['Drupal'].settings.baseUrl = this.baseUrl;
            // drupal-8
            window['drupalSettings'] = window['drupalSettings'] || {};
        }
        if (this.version === 'drupal-8') {
            if (window && !window['jDrupal']) {
                console.error('ERROR: jDrupal is not defined in the global namespace.');
                return;
            }
            this.jDrupal = jDrupal;
            jDrupal.config('sitePath', this.options.protocol + '//' + this.options.domain);
        }
        if ('withCredentials' in new XMLHttpRequest) {
            this.cors = true;
        }
    };
    ;
    Drupal.prototype.login = function (username, password) {
        var self = this;
        return new Promise(function (resolve, reject) {
            jDrupal.userLogin(username, password).then(function () {
                self.user = jDrupal.currentUser();
                self.api.setCredentials(jDrupal.settings, 'drupal:authUser:' + self.domain);
                self.authenticated = true;
                resolve();
            });
        });
    };
    Drupal.prototype.logout = function () {
        var self = this;
        return new Promise(function (resolve, reject) {
            // fixme: drupal permission denied;
            //jDrupal.userLogout().then(function() {
            // this.api.logout('drupal:authUser:'+self.domain,true);
            self.api.logout('drupal:authUser:' + self.domain);
            self.authenticated = false;
            console.log('logged out');
            resolve();
            //});
        });
    };
    Drupal.prototype.getParams = function () {
        var self = this;
        return new Promise(function (resolve, reject) {
            var url = 'index.php/rest/params';
            if (self.version === 'drupal-7') {
                url = '?q=rest/app_params.json';
            }
            self.api.get(url, { _format: 'json' }).then(function (result) {
                self.model.siteParams = self.siteParams = result;
                resolve(result);
            });
        });
    };
    ;
    Drupal.prototype.getView = function (viewEntity, params) {
        var _this = this;
        if (params === void 0) { params = undefined; }
        return new Promise(function (resolve, reject) {
            var entity = viewEntity;
            _this.api.get(entity.attributes.display.rest_export_1.display_options.path, params).then(function (res) {
                _this.model.views[entity.attributes.id] = res;
                resolve();
            });
        });
    };
    Drupal.prototype.getAppNode = function (uuid) {
        var _this = this;
        return new Promise(function (resolve) {
            _this.jsonApi.getNode(uuid, 'app').then(function (node) {
                var dataPromises = [];
                var attributes = node.data.attributes;
                if (attributes.field_cache === true) {
                    _this.jsonApi.cache = attributes.field_cache;
                }
                // fixme: all collections
                if (attributes.field_preload_collections) {
                    dataPromises.push(_this.jsonApi.getAllCollections(true));
                }
                // get entity reference fields
                Object.keys(_this.model.entities).forEach(function (k, i) {
                    var entity = _this.model.entities[k];
                    if (entity.type == 'menu--menu') {
                        dataPromises.push(_this.menuLoad(entity.attributes.id, attributes.cache));
                    }
                    if (entity.type == 'view--view') {
                        dataPromises.push(_this.getView(entity));
                    }
                    if (entity.data && entity.data.type.match('node--')) {
                        if (entity.data.attributes.uuid !== uuid) {
                            dataPromises.push(_this.jsonApi.getNode(entity.data.attributes.uuid));
                        }
                    }
                });
                _this.getSiteData(dataPromises).then(function () {
                    resolve();
                });
            });
        });
    };
    Drupal.prototype.getSiteData = function (promises) {
        var self = this;
        return new Promise(function (resolve, reject) {
            Promise.all(promises).then(function (responses) {
                if (self.cache) {
                    self.saveLocalModel(self.model, self.domain);
                }
                resolve();
            });
        });
    };
    Drupal.prototype.getLocalStorageCredentials = function () {
        var self = this;
        return new Promise(function (resolve, reject) {
            var credentials = self.api.getCredentials('drupal:authUser:' + self.domain);
            if (credentials) {
                for (var k in credentials) {
                    jDrupal.settings[k] = credentials[k];
                }
                var auth = atob(credentials.auth_hash);
                self.login(auth.split(':')[0], auth.split(':')[1]).then(function () {
                    resolve();
                });
            }
            else {
                resolve();
            }
        });
    };
    Drupal.prototype.menuLoad = function (mid, preloadNodes) {
        if (preloadNodes === void 0) { preloadNodes = false; }
        var self = this;
        return new Promise(function (resolve, reject) {
            self.api.get('entity/menu/' + mid + '/tree', { _format: 'hal_json' }).then(function (res) {
                // self.api.getOud('entity/menu/' + mid + '/tree?_format=hal_json').toPromise().then((res) => {
                // const menu: any = res.json();
                var menu = res;
                self.model.menus[mid] = menu;
                if (preloadNodes) {
                    var nids_1 = [];
                    menu.forEach(function (item) {
                        if (item.link.route_parameters.node) {
                            nids_1.push(item.link.route_parameters.node);
                        }
                    });
                    // todo: use jsonApi
                    self.jsonApi.getNodes(nids_1).then(function () {
                        console.log(nids_1);
                        // self.nodesLoad(nids).then(() => {
                        resolve(menu);
                    });
                }
                else {
                    resolve(menu);
                }
            });
        });
    };
    Drupal.prototype.bookLoad = function (bid, preload) {
        if (preload === void 0) { preload = false; }
        var self = this;
        return new Promise(function (resolve, reject) {
            self.api.get('rest/book_tree/' + bid, { _format: 'hal_json' }).then(function (res) {
                self.model.books[bid] = res;
                var nids = self.parseBookTree(bid);
                if (preload) {
                    // self.nodesLoad(nids).then(() => {
                    self.jsonApi.getNodes(nids).then(function () {
                        resolve(res);
                    });
                }
                else {
                    resolve(res);
                }
            });
        });
    };
    Drupal.prototype.parseBookTree = function (bid) {
        var data = this.model.books[bid];
        var below, items, nids, k, kk;
        items = [];
        nids = [];
        for (k in data) {
            below = data[k].below;
        }
        for (k in below) {
            var item = void 0;
            for (kk in below[k]) {
                item = below[k];
                item.link.route_parameters = { node: below[k].link.nid };
                item.link.href = '/node/' + item.link.nid;
                nids.push(below[k].link.nid);
            }
            items.push(item);
        }
        this.model.menus['book_' + bid] = items;
        return nids;
    };
    // todo: remove: deprecated
    Drupal.prototype.nodeLoad = function (nid) {
        var self = this;
        return new Promise(function (resolve, reject) {
            if (self.cache && self.model.nodes[nid]) {
                resolve(self.model.nodes[nid]);
            }
            else {
                jDrupal.nodeLoad(nid).then(function (node) {
                    self.model.nodes[node.entity.nid[0].value] = node;
                    self.model.entities[node.entity.uuid[0].value] = node.entity;
                    resolve(node);
                });
            }
        });
    };
    // todo: remove: deprecated
    Drupal.prototype.nodesLoad = function (nids) {
        var self = this;
        var promises = [];
        return new Promise(function (resolve, reject) {
            for (var k in nids) {
                promises.push(self.nodeLoad(nids[k]));
            }
            Promise.all(promises).then(function (responses) {
                resolve();
            });
        });
    };
    // todo: remove: deprecated
    Drupal.prototype.createNode = function (data) {
        var node = {};
        for (var key in data) {
            node[key] = [{ value: data[key] }];
        }
        node.title = [{ value: data.title }];
        node.type = [{ target_id: data.type }];
        node._links = {
            type: {
                href: jDrupal.restPath() + 'rest/type/node/' + data.type
            }
        };
        // if(data.type==='iframe'){
        //     field_iframe: [ { target_id: data.type } ]
        // }
        return new jDrupal.Node(node);
    };
    return Drupal;
}());
exports.Drupal = Drupal;
// (function() {
//     'use strict';
//
//
//         this.connect = function() {
//             var defer = $q.defer();
//             var self = this;
//             // fixme: drupal-8 + use SystemConnect resource, remove jquery dependency
//             $.ajax({
//                 type: "POST",
//                 url: self.baseUrl + "?q=rest/system/connect",
//                 dataType: "json",
//                 contentType: "application/x-www-form-urlencoded",
//                 success: function(data) {
//                     //$cookies[data.session_name] = data.sessid;
//                     self.sessionQuery = data.session_name + '=' + data.sessid;
//                     $http.defaults.headers.common['DrupalCookie'] = self.sessionQuery;
//                     $.ajaxSetup({
//                         beforeSend: function(request) {
//                             request.setRequestHeader('DrupalCookie',self.sessionQuery);
//                         }
//                     });
//                     self.user = data.user;
//                     self.sessid = data.sessid;
//                     self.session_name = data.session_name;
//                     defer.resolve(data)
//                 }
//             });
//             return defer.promise;
//         };
//
//         this.login = function(user,pass){
//             var username = user || this.default_user;
//             var password = pass || this.default_pass;
//             var defer = $q.defer();
//             var self = this;
//             var url;
//             if(self.version === 'drupal-8'){
//                 url = 'index.php/user/login';
//             }
//             if(self.version === 'drupal-7'){
//                 url = '?q=rest/user/login';
//             }
//             // fixme: use $http service
//             $.ajax({
//                 type: "POST",
//                 data: {username: username,password: password },
//                 url: self.baseUrl + url,
//                 dataType: "json",
//                 contentType: "application/x-www-form-urlencoded",
//                 success: function (data) {
//                     $cookies[data.session_name] = data.sessid;
//                     self.sessionQuery = data.session_name + '=' + data.sessid;
//                     $http.defaults.headers.common['DrupalCookie'] = self.sessionQuery;
//                     $.ajaxSetup({
//                         beforeSend: function(request) {
//                             request.setRequestHeader('DrupalCookie',self.sessionQuery);
//                         }
//                     });
//                     self.user = data.user;
//                     self.sessid = data.sessid;
//                     self.session_name = data.session_name;
//                     self.getToken().then(function(token) {
//                         $log.log('login success');
//                         defer.resolve(data);
//                     });
//                 },
//                 error: function (data) {
//                     $log.error('login error');
//                     $log.log(data);
//                 }
//             });
//             return defer.promise;
//         };
//
//         this.initApi = function(version){
//             var self = this;
//             this.node = function(){};
//             this.node.get = function(options,succes){
//                 var defer = $q.defer();
//                 var cache = self.cache;
//                 if(self.model.nodes[options.nid] && cache === true){
//                     if(succes){
//                         succes.call(null,self.model.nodes[options.nid]);
//                     }
//                     defer.resolve(self.model.nodes[options.nid]);
//                 }else{
//                     return self.Node.get({nid:options.nid},function(result){
//                         if(result.uuid && typeof result.uuid === "string") {
//                             self.setEntity(result.uuid, result); // drupal-7
//                         }
//                         if(result.uuid && result.uuid && typeof result.uuid !== "string") {
//                             self.setEntity(result.uuid[0].value, result); // drupal-8
//                         }
//                         self.model.nodes[$filter('nid')(result)] = result;
//                         if(succes){
//                             succes.call(null,result);
//                         }
//                         defer.resolve(result);
//                     })
//                 };
//                 return defer.promise;
//             };
//             this.node.save = function saveNode(node,succes){
//                 if(node.nid) {
//                     self.Node.update(node,function(res){
//                         succes.call(this,res);
//                     },function(err){
//                     })
//                 }else{
//                     self.Node.create(node,function(res){
//                         succes.call(this,res);
//                         // defer.resolve(res);
//                     },function(err){
//                         // defer.resolve(res);
//                     })
//                 }
//             };
//             this.menu = function(){};
//             this.menu.get = function(options,succes){
//                 return self.Menu.get(options,function(result){
//                     self.model.menus[options.mid] = result;
//                     succes.call(this,result);
//                 });
//             };
//             this.views = function(){};
//             this.views.get = function(options,succes){
//                 var defer = $q.defer();
//                 return self.Views.get(options,function(result){
//                     self.model.views[options.view_name] = result;
//                     if(succes){
//                         succes.call(null,result);
//                     }
//                     defer.resolve(result);
//                 });
//                 return defer.promise;
//             };
// //            case 'site.getParams':
// //                    path = 'app/site/getParams';
// //                    break;
// //                case 'site.getNodes':
// //                    path = 'app/site/getNodes/' + encodeURI(args.nids);
// //                    break;
// //                case 'site.getBook':
// //                    path = 'app/book/' + args.bid;
// //                    break;
//         };
//
//         this.initResources = function(version){
//             var pre, url, urlPost, trail;
//
//             if(version === 'drupal-7'){
//                 pre = '?q=';
//                 url = 'rest/node';
//                 urlPost = 'rest/node';
//                 trail = '.json';
//             }
//             if(version === 'drupal-8'){
//                 pre = 'index.php/';
//                 url = 'node';
//                 urlPost = 'entity/node';
//                 trail = '?_format=hal_json';
//                 // trail = '?_format=json';
//             }
//             // node resource
//             this.Node = $resource(this.baseUrl + pre + url + '/:nid' + trail, {}, {
//                 create: { method: 'POST',withCredentials:true,isArray:false,url:this.baseUrl + pre + urlPost + '' + trail },
//                 get: { method: 'GET',isArray:false,url:this.baseUrl + pre + url + '/:nid' + trail},
//                 update: { method: 'POST',withCredentials:true,isArray:false,url:this.baseUrl + pre + url + '/:nid' + trail },
//                 delete: { method: 'DELETE',withCredentials:true,isArray:true,url:this.baseUrl + pre + url + '/:nid' + trail}
//             });
//             this.Node.prototype.update = function(node) {
//                 //return this.Node.update({nid:$filter('nid')(this)},angular.extend({},this,{nid:undefined}),node);
//                 return this.Node.update({nid:this.nid},angular.extend({},this,{nid:undefined}),node);
//             };
//
//             // views resource
//             var path;
//             if(version === 'drupal-7'){
//                 path = this.baseUrl + '?:view_arguments&q=rest/views/:view_name';
//             }
//             if(version === 'drupal-8'){
//                 path = this.baseUrl + pre + 'rest/views/:view_name';
//             }
//             this.Views = $resource(path + trail, {}, {
//                 get: {
//                     method: 'GET',
//                     isArray:true,
//                     withCredentials:true,
//                     url: path + trail
//                 }
//             });
//
//             // comment resource
//             this.Comment = $resource(this.baseUrl + '?q=rest/comment/:cid' + trail, {}, {
//                 get: { method: 'GET',isArray:false },
//                 update: { method: 'POST',isArray:false }
//             });
//             this.Comment.prototype.update = function (comment) {
//                 return this.Comment.update({cid: this.cid}, angular.extend({}, this, {cid: undefined}), comment);
//             };
//             this.Comments = $resource(this.baseUrl + '?:query&q=rest/comment' + trail, {}, {
//                 // ?pagesize=200 // todo:
//                 get: {method: 'GET',isArray:true}
//             });
//
//
//             this.Menu = $resource(this.baseUrl + '?q=rest/menu/:mid' + trail, {}, {
//                 get: { method: 'GET',isArray:false },
//             });
//
//             this.TaxonomyVocabulary = $resource(this.baseUrl + '?parameters[vid]=:vid&q=rest/taxonomy_vocabulary' + trail, {}, {
//                 get: {method:'GET',isArray:true,url:this.baseUrl + '?parameters[vid]=:vid&q=rest/taxonomy_vocabulary' + trail },
//             });
//             this.TaxonomyTerm = $resource(this.baseUrl + '?parameters[tid]=:tid&q=rest/taxonomy_term' + trail, {}, {
//                 get: {method: 'GET',isArray:true},url:this.baseUrl + '?parameters[tid]=:tid&q=rest/taxonomy_term' + trail
//             });
//
//             this.SystemConnect = $resource(this.baseUrl + '?q=rest/system/connect' + trail, {}, {
//                 post: {
//                     method: 'POST',
//                     withCredentials:true,
//                     isArray:true,
//                     params:{},
//                     headers: {'Content-Type':'application/x-www-form-urlencoded','X-CSRF-Token': this.token}
//                 }
//             });
//
//             // custom: drupal 7
//             this.queryNodes= function(params,callback) {
//                 var query = '';
//                 for(var k in params){
//                     query+='c['+k+']='+params[k]+'&';
//                 };
//                 $http.get(this.baseUrl+'?'+query+'q=rest/node' + trail).success(callback).error(function(){$log.log(arguments)});
//             };
//
//             this.getTaxonomyTree = function(vid,callback,maxDepth){
//                 var data = $.param({vid:vid,maxDepth:maxDepth||10});
//                 $http.post(this.baseUrl+ pre + 'rest/taxonomy_vocabulary/getTree' + trail, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded','X-CSRF-Token': this.token}}
//                 ).success(callback);
//             };
//         };
//
//         //this.queryNodes= function(params,callback) {
//         //    var query = '';
//         //    for(var k in params){
//         //        query+='c['+k+']='+params[k]+'&';
//         //    };
//         //    $http.get(this.baseUrl+'?'+query+'q=rest/node' + trail).success(callback).error(function(){$log.log(arguments)});
//         //};
//         //
//         //this.getTaxonomyTree = function(vid,callback,maxDepth){
//         //    var data = $.param({vid:vid,maxDepth:maxDepth||10});
//         //    $http.post(this.baseUrl+'?q=rest/taxonomy_vocabulary/getTree' + trail, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded','X-CSRF-Token': this.token}}
//         //    ).success(callback);
//         //};
//
//         this.getToken = function(){
//             var defer = $q.defer();
//             var self = this;
//             var url;
//             if(self.version === 'drupal-8'){
//                 url = this.baseUrl + 'index.php/rest/session/token?_format=hal_json';
//             }
//             if(self.version === 'drupal-7'){
//                 url = this.baseUrl + '?q=services/session/token';
//             }
//             $http.get(url).then(function(token){
//                 self.token = token.data;
//                 //$cookies['token_'+self.domain] = token.data;
//                 $http.defaults.headers.common['X-CSRF-Token'] = token.data;
//                 $.ajaxSetup({
//                     beforeSend: function(request) {
//                         request.setRequestHeader("X-CSRF-Token",token.data);
//                     }
//                 });
//                 defer.resolve(token)
//             });
//             return defer.promise;
//         };
//
//         this.setEntity = function(uuid,value) {
//             this.model.entities[uuid] = value;
//         };
//         this.getEntity = function(uuid) {
//             if(this.model.entities[uuid]){
//                 return this.model.entities[uuid];
//             }
//         };
//         //this.setFieldEntities = function(el){
//         //    var self = this;
//         //    el.find("div[data-quickedit-field-id]").each(function(i,el){
//         //        var entity = {};
//         //        var uuid = AppService.getUUID();
//         //        var field = el;
//         //        var data = angular.element(field).attr('data-quickedit-field-id').split('/');
//         //        var field_type = data[2];
//         //        var field_class = 'field--name-'+field_type.replace('_','-');
//         //        angular.element(field).addClass(field_class);
//         //
//         //        entity['type'] = 'field';
//         //        entity['field_type'] = field_type;
//         //        entity['field_class'] = field_class;
//         //        entity['field_context'] = data;
//         //        entity['element'] = field;
//         //
//         //        self.setEntity(uuid,entity)
//         //    })
//         //};
//         // todo: ??
//         this.getEntityId = function(uuid) {
//             if(this.model.entities[uuid]){
//                 var arr = this.model.entities[uuid]._links.self.href.split('/');
//                 return arr[arr.length-1].split('?')[0];
//             }
//         };
//
//
//         //this.checkRestServer = function(url){
//         //    var request;
//         //    if($window.XMLHttpRequest)
//         //        request = new XMLHttpRequest();
//         //    else
//         //        request = new ActiveXObject("Microsoft.XMLHTTP");
//         //    request.open('GET',url , false);
//         //    request.send(); // there will be a 'pause' here until the response to come.
//         //    if (request.status === 404) {
//         //        $log.error("Rest resource 'params' on "+this.domain+" is not enabled.");
//         //    }
//         //}
//
//     }
//
// })();
//# sourceMappingURL=drupal.js.map