import { ConfigService } from '@rxap/config';
import { UpdateEnvironment } from '@rxap/environment';
import { NGXLogger } from 'ngx-logger';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { setRemoteUrlResolver, setRemoteDefinitions } from '@nx/angular/mf';
import { importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

class Application {
    constructor(environment, options = {}, configLoadOptions) {
        this.environment = environment;
        this.options = options;
        this.configLoadOptions = configLoadOptions;
        this.app = null;
        this.logger = null;
        this.config = null;
        this._beforeList = [];
        this._afterList = [];
    }
    async bootstrap() {
        await this.prepareEnvironment(this.environment);
        await this.loadConfig(this.environment);
        this.prepareConfig(this.options);
        await this.handleBefore(new ConfigService(ConfigService.Config), this.options);
        try {
            this.app = await this.create();
        }
        catch (e) {
            throw new Error(`Angular app creation failed: ${e.message}`);
        }
        if (!this.app) {
            throw new Error('Angular app creation failed');
        }
        this.logger = this.app.injector.get(NGXLogger);
        this.config = this.app.injector.get(ConfigService);
        if (!this.logger) {
            throw new Error('Could not inject a NGXLogger instance');
        }
        if (!this.config) {
            throw new Error('Could not inject a ConfigService instance');
        }
        await this.handleAfter(this.app, this.logger, this.config);
    }
    before(fnc) {
        this._beforeList.push(fnc);
    }
    after(fnc) {
        this._afterList.push(fnc);
    }
    async handleBefore(config, options) {
        for (const before of this._beforeList) {
            await before(config, options);
        }
    }
    async handleAfter(app, logger, config) {
        for (const after of this._afterList) {
            await after(app, config, logger);
        }
    }
    async loadConfig(environment) {
        await ConfigService.Load(this.configLoadOptions, environment);
    }
    async prepareEnvironment(environment) {
        await UpdateEnvironment(environment);
    }
}

class ModuleApplication extends Application {
    constructor(environment, moduleType, options, configLoadOptions) {
        super(environment, options, configLoadOptions);
        this.moduleType = moduleType;
    }
    create() {
        return platformBrowserDynamic(this.options.extraProviders)
            .bootstrapModule(this.moduleType, this.options.compilerOptions);
    }
    prepareConfig(config) {
        config.extraProviders ??= [];
        config.compilerOptions ??= [];
    }
}

/**
 * @deprecated It is not possible to use the `import` statement in the `main.ts` file. This results in a runtime error.
 * @param environment
 */
async function SetupDynamicMfe(environment) {
    const manifest = environment.moduleFederation?.manifest;
    if (!manifest) {
        const release = environment.tag || environment.branch || 'latest';
        setRemoteUrlResolver((remoteName) => `${location.origin}/__mfe/${release}/${remoteName}`);
    }
    else {
        let definitions;
        if (typeof manifest === 'object') {
            definitions = manifest;
        }
        else {
            definitions = await fetch(manifest).then((res) => res.json());
        }
        setRemoteDefinitions(definitions);
    }
}

class StandaloneApplication extends Application {
    constructor(environment, rootComponent, options, configLoadOptions = {
        url: `${environment.origin ?? location.origin}/api/configuration/${environment.tag ??
            'latest'}/${environment.app}`,
    }) {
        super(environment, options, configLoadOptions);
        this.rootComponent = rootComponent;
    }
    importProvidersFrom(...sources) {
        this.options.providers ??= [];
        this.options.providers.push(importProvidersFrom(...sources));
    }
    create() {
        return bootstrapApplication(this.rootComponent, this.options);
    }
    prepareConfig(config) {
        config.providers ??= [];
    }
}

// region 
// endregion

/**
 * Generated bundle index. Do not edit.
 */

export { Application, ModuleApplication, SetupDynamicMfe, StandaloneApplication };
//# sourceMappingURL=rxap-ngx-bootstrap.mjs.map
