var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { User, Util } from "../lib";
import { BaseService } from "../lib/index";
import { PermissionsService } from "../lib/permissions/permissions-service";
import { tap } from 'rxjs/operators';
// redux
import { createStore } from '../lib/rx/rx-redux';
import { RxUtil } from "../lib/rx/rx-util";
import baseReducer from '../lib/rx/redux/base-reducer';
import { baseActions } from '../lib/rx/redux/base-actions';
import appReducer from './app-reducer';
import { appActions } from './app-actions';
const singleton = Symbol();
const singletonEnforcer = Symbol();
export class AppService {
    constructor(enforcer) {
        this.actions = appActions;
        this.baseUrl = '';
        this.loading = true;
        this.authenticated = false;
        this.errorMessage = '';
        if (enforcer !== singletonEnforcer) {
            throw new Error('Cannot construct singleton');
        }
        this.base = BaseService.instance;
        this.permissions = PermissionsService.instance;
        this.config = this.base.config;
        this.user = new User('visitor');
        // redux
        this.initStores();
        // this.test()
    }
    init(appRoot, baseUrl = '') {
        return __awaiter(this, void 0, void 0, function* () {
            if (baseUrl !== '')
                this.baseUrl = baseUrl;
            this.appRoot = appRoot;
            yield this.base.initApp(this.baseUrl + '/assets/config.json', true, '_emaApp');
            yield this.permissions.loadRules(this.baseUrl + '/assets/permissions.json', true, 'rules');
            this.baseUrl = baseUrl;
            this.base.translation.use(this.config.get('language'));
            this.data = {};
            // this.data.permissions = await Util.fetchJson(this.baseUrl + '/assets/permissions.json');
            this.data.manifest = yield Util.fetchJson(this.baseUrl + '/assets/collection-manifest.json');
            this.data.mockData = yield Util.fetchJson(this.baseUrl + '/assets/data/mock-data.json');
            this.data.dwpData = yield Util.fetchJson(this.baseUrl + '/assets/data/mock-dwp.json');
            this.data.swaggerData = yield Util.fetchJson(this.baseUrl + '/assets/data/apiSwagger.json');
            // let swaggerData = await this.fetchJson(this.baseUrl + '/assets/data/mock-swagger.json');
            this.collectionManifest = this.data.manifest;
            this.parseComponents();
            this.initHistory();
            if (window.document.location.hostname.match('localhost'))
                this.config.set('dev', true);
            return this.data;
        });
    }
    initStores() {
        return __awaiter(this, void 0, void 0, function* () {
            this.store$ = createStore(appReducer, {});
            this.config$ = createStore(baseReducer);
            // this.store$.pipe().subscribe((config) => {
            this.store$.pipe(tap(RxUtil.log())).subscribe((state) => {
                //
            });
            this.config$.pipe().subscribe((config) => {
                this.base.config.add(config, true);
            });
        });
    }
    test() {
        // dispatch(this.actions.changeName, 'Karel').subscribe((arg) => {
        //     console.log('------',arg);
        // })
        this.actions.changeName('Bob');
        baseActions.loadConfig(this.baseUrl + '/assets/config.json');
        baseActions.setConfig('foo', 'bar');
        console.log(this.user.roles);
        this.user.addRole('AUTHENTICATED');
        this.user.addRole('DEVELOPER');
        console.log(this.user.roles);
        this.user.removeRole('AUTHENTICATED');
        console.log(this.user.roles);
        console.log(this.user.hasRole('DEVELOPER'));
        console.log(this.user.hasRole('AUTHENTICATED'));
        console.log(this.config.all());
        // var int$ = interval(4000)
        // int$.pipe(tap(RxUtil.log())).subscribe((v) => {
        //     // console.log(v+'--------yep');
        //     appActions.changeName(v+ ' - Bob Stoute');
        //     baseActions.addConfig({count: v})
        //     // baseActions.loadConfig(this.baseUrl + '/assets/config.json');
        //     if(v === 10) {
        //         // int$.
        //     }
        // })
    }
    // todo: set router classes on body
    initHistory() {
        // console.log(this);
        if (typeof window !== 'undefined' && window.history) {
            // window.addEventListener("pushstate", function(e) {
            //     console.log(JSON.parse(window.history.state));
            // });
            // window.addEventListener("popstate", function(e) {
            //     console.log(JSON.parse(window.history.state));
            // });
        }
    }
    parseComponents() {
        let allComps = Util.copy(this.data.manifest.components);
        let components = [];
        allComps.map((c) => {
            let tag = c.tag;
            let ignore = false;
            this.config.get('componentsIgnorePatterns').forEach((p) => {
                if (tag.match(p)) {
                    ignore = true;
                }
            });
            if (!ignore) {
                components.push(c);
            }
        });
        this.components = components;
    }
    showFlashMessage(message, type, duration = 2000) {
        document.querySelector('ema-flash-message').show(message, type, duration);
    }
    static get instance() {
        if (!this[singleton]) {
            this[singleton] = new AppService(singletonEnforcer);
        }
        return this[singleton];
    }
}
//# sourceMappingURL=app-service.js.map