import { Component, ViewChild } from '@angular/core';
import { ApplicationService } from '@c8y/client';
import { PluginsService, WizardComponent } from '@c8y/ngx-components';
import { BehaviorSubject, combineLatest, from, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { EcosystemService } from '@c8y/ngx-components/ecosystem/shared';
import { ApplicationPropertiesFormComponent } from '@c8y/ngx-components/ecosystem/shared';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components/ecosystem/shared";
import * as i2 from "@c8y/client";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@angular/common";
import * as i5 from "@angular/forms";
export class InstallFromPackageComponent {
    constructor(ecosystemService, applicationService, wizardComponent, pluginsService) {
        this.ecosystemService = ecosystemService;
        this.applicationService = applicationService;
        this.wizardComponent = wizardComponent;
        this.pluginsService = pluginsService;
        this.deployedWithSuccess = false;
        this.isDeployed = false;
        this.model = {
            selected: undefined,
            binary: {
                id: undefined
            }
        };
        this.canDeploy = false;
        this.onInput = new BehaviorSubject('');
    }
    async ngOnInit() {
        this.loadPackages();
    }
    back() {
        this.wizardComponent.reset();
    }
    clean() {
        this.selectedPackage = undefined;
        this.versions$ = undefined;
        this.model = {
            selected: undefined,
            binary: {
                id: undefined
            }
        };
    }
    cancel() {
        this.wizardComponent.close();
    }
    async deployApp() {
        this.inProgress = true;
        const formGroupValue = this.applicationPropertiesForm.formGroup.getRawValue();
        const { contextPath, license, name } = this.selectedPackage;
        const type = this.pluginsService.getPackageType(this.selectedPackage);
        const licensedApp = {
            contextPath,
            license,
            name,
            type,
            version: this.model.selected.version
        };
        const licensesVerifiedByUser = await this.ecosystemService.verifyLicenses([licensedApp]);
        if (!licensesVerifiedByUser) {
            this.cancel();
            return;
        }
        // Verify if selected package version is compatible with current platform versions.
        this.selectedPackage.manifest.version = this.model.selected.version;
        const verifyVersionCompatibility = await this.ecosystemService.verifyBlueprintVersionsCompatibility(this.selectedPackage.manifest);
        if (!verifyVersionCompatibility) {
            this.cancel();
            return;
        }
        try {
            await this.ecosystemService.deployApp(this.selectedPackage, formGroupValue, this.model);
            this.deployedWithSuccess = true;
        }
        catch (error) {
            this.ecosystemService.alertError(error);
        }
        finally {
            this.markAsDeployed();
        }
    }
    onAppVersionSelect(appVersion) {
        Object.assign(this.model, {
            selected: appVersion
        });
        this.canDeploy = true;
    }
    async selectPackage(selectedPackage) {
        const apps = await this.ecosystemService.getHostedAndPackageApplications();
        this.newAppConfig = this.ecosystemService.getUniqueAppConfig(selectedPackage, apps);
        this.selectedPackage = selectedPackage;
        this.loadSelectedPackageVersions();
    }
    loadSelectedPackageVersions() {
        this.versions$ = combineLatest([
            this.getAppVersions(this.selectPackage),
            this.onInput.asObservable()
        ]).pipe(map(([resultList, filterStr]) => {
            this.canDeploy = false;
            const versionsFilteredByStr = this.filterAppVersions(resultList.data, filterStr);
            const sortedAppVersions = this.pluginsService.sortVersions({
                list: versionsFilteredByStr,
                path: ['version']
            }, 'desc');
            this.setInitialValueForInput(sortedAppVersions);
            return { data: sortedAppVersions, res: resultList.res };
        }));
    }
    getAppVersions(mo) {
        const versions = mo?.applicationVersions;
        return versions && versions.length > 0
            ? of({ data: versions, res: undefined })
            : from(this.applicationService.listVersions(this.selectedPackage.id));
    }
    setInitialValueForInput(versions) {
        if (!this.model.selected && versions.length > 0) {
            const latest = versions.find(v => v.tags.includes('latest'));
            this.model.selected = latest || versions[0];
            this.canDeploy = true;
        }
    }
    filterAppVersions(appVersions, filterStr) {
        return filterStr === ''
            ? appVersions
            : appVersions.filter(appVersion => appVersion.version.includes(filterStr));
    }
    markAsDeployed() {
        this.isDeployed = true;
        this.inProgress = false;
    }
    async loadPackages() {
        const applications = await this.ecosystemService.getPackageApplications();
        this.packages = applications.filter(app => this.ecosystemService.isPackageBlueprint(app));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: InstallFromPackageComponent, deps: [{ token: i1.EcosystemService }, { token: i2.ApplicationService }, { token: i3.WizardComponent }, { token: i3.PluginsService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: InstallFromPackageComponent, selector: "c8y-install-from-package", viewQueries: [{ propertyName: "applicationPropertiesForm", first: true, predicate: ApplicationPropertiesFormComponent, descendants: true }], ngImport: i0, template: "<c8y-wizard-header>\n  <i [c8yIcon]=\"'big-parcel'\"></i>\n  <h4\n    id=\"modal-title\"\n    translate\n  >\n    Install from extension package\n  </h4>\n</c8y-wizard-header>\n<c8y-wizard-body>\n  <ng-container *ngIf=\"!selectedPackage\">\n    <div\n      class=\"modal-inner-scroll\"\n      id=\"modal-body\"\n    >\n      <p class=\"p-16 text-medium text-center separator-bottom sticky-top bg-level-0\">\n        {{ 'Select from available extension packages' | translate }}\n      </p>\n\n      <c8y-ui-empty-state\n        [icon]=\"'big-parcel'\"\n        [title]=\"'No extension packages to display.' | translate\"\n        *ngIf=\"!packages?.length\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n\n      <div\n        class=\"c8y-wizard-list-nav\"\n        style=\"min-height: 257px\"\n        *ngIf=\"packages?.length\"\n      >\n        <button\n          class=\"list-group-item text-truncate\"\n          title=\"{{ package.name }}\"\n          type=\"button\"\n          *ngFor=\"let package of packages\"\n          (click)=\"selectPackage(package)\"\n        >\n          <i\n            class=\"list-group-icon\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <span [innerText]=\"package.name\"></span>\n        </button>\n      </div>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"!isDeployed && selectedPackage\">\n    <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-level-0\">\n      {{ 'Provide application details' | translate }}\n    </p>\n    <div\n      class=\"d-flex d-col a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n    >\n      <c8y-application-properties-form\n        class=\"d-block fit-w\"\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div\n          class=\"d-block fit-w bg-gray-white\"\n          [ngStyle]=\"{ padding: '0 16px' }\"\n        >\n          <label\n            for=\"packageVersion\"\n            translate\n          >\n            Use extension package version\n          </label>\n          <c8y-form-group>\n            <c8y-typeahead\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              name=\"packageVersion\"\n              [(ngModel)]=\"model.selected\"\n              (onSearch)=\"onInput.next($event)\"\n              [displayProperty]=\"'version'\"\n              [required]=\"true\"\n              [hideNew]=\"true\"\n              [container]=\"'body'\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let version of versions$; loadMore: 'auto'; notFound: notFoundTemplate\"\n                (click)=\"onAppVersionSelect(version)\"\n                [active]=\"model.selected === version\"\n              >\n                <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n                <span\n                  [ngStyle]=\"{\n                    display: 'flex',\n                    'flex-direction': 'row',\n                    'align-content': 'center',\n                    'justify-content': 'space-between',\n                    'align-items': 'center'\n                  }\"\n                >\n                  <c8y-highlight\n                    [text]=\"version.version || '--'\"\n                    [pattern]=\"onInput | async\"\n                  ></c8y-highlight>\n\n                  <span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngFor=\"let tag of version.tags\"\n                    >\n                      {{ tag }}\n                    </span>\n                  </span>\n                </span>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li\n                  class=\"bg-gray-lighter p-8\"\n                  *ngIf=\"(onInput | async)?.length > 0 && (versions$ | async)?.data?.length === 0\"\n                >\n                  <span translate>No match found.</span>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        class=\"text-center d-block\"\n        [message]=\"'Installing\u2026' | translate\"\n        *ngIf=\"inProgress\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      class=\"d-flex a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n    >\n      <c8y-operation-result\n        class=\"lead\"\n        type=\"success\"\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n      ></c8y-operation-result>\n    </div>\n    <ng-template #failedDeploy>\n      <div\n        class=\"d-flex a-i-center j-c-center\"\n        style=\"min-height: 257px\"\n      >\n        <c8y-operation-result\n          class=\"lead\"\n          type=\"error\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ 'Back' | translate }}\"\n    type=\"button\"\n    *ngIf=\"!isDeployed\"\n    (click)=\"selectedPackage ? clean() : back()\"\n    [disabled]=\"inProgress\"\n  >\n    {{ 'Back' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\"\n    type=\"button\"\n    (click)=\"cancel()\"\n  >\n    {{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\n  </button>\n\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Install' | translate }}\"\n    type=\"button\"\n    (click)=\"deployApp()\"\n    [disabled]=\"inProgress || !packages?.length\"\n    *ngIf=\"!isDeployed\"\n  >\n    {{ 'Install' | translate }}\n  </button>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "component", type: i3.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i3.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3.WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "component", type: i3.WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "component", type: i3.WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "component", type: i1.ApplicationPropertiesFormComponent, selector: "c8y-application-properties-form", inputs: ["application", "disabled"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: InstallFromPackageComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-install-from-package', template: "<c8y-wizard-header>\n  <i [c8yIcon]=\"'big-parcel'\"></i>\n  <h4\n    id=\"modal-title\"\n    translate\n  >\n    Install from extension package\n  </h4>\n</c8y-wizard-header>\n<c8y-wizard-body>\n  <ng-container *ngIf=\"!selectedPackage\">\n    <div\n      class=\"modal-inner-scroll\"\n      id=\"modal-body\"\n    >\n      <p class=\"p-16 text-medium text-center separator-bottom sticky-top bg-level-0\">\n        {{ 'Select from available extension packages' | translate }}\n      </p>\n\n      <c8y-ui-empty-state\n        [icon]=\"'big-parcel'\"\n        [title]=\"'No extension packages to display.' | translate\"\n        *ngIf=\"!packages?.length\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n\n      <div\n        class=\"c8y-wizard-list-nav\"\n        style=\"min-height: 257px\"\n        *ngIf=\"packages?.length\"\n      >\n        <button\n          class=\"list-group-item text-truncate\"\n          title=\"{{ package.name }}\"\n          type=\"button\"\n          *ngFor=\"let package of packages\"\n          (click)=\"selectPackage(package)\"\n        >\n          <i\n            class=\"list-group-icon\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <span [innerText]=\"package.name\"></span>\n        </button>\n      </div>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"!isDeployed && selectedPackage\">\n    <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-level-0\">\n      {{ 'Provide application details' | translate }}\n    </p>\n    <div\n      class=\"d-flex d-col a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n    >\n      <c8y-application-properties-form\n        class=\"d-block fit-w\"\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div\n          class=\"d-block fit-w bg-gray-white\"\n          [ngStyle]=\"{ padding: '0 16px' }\"\n        >\n          <label\n            for=\"packageVersion\"\n            translate\n          >\n            Use extension package version\n          </label>\n          <c8y-form-group>\n            <c8y-typeahead\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              name=\"packageVersion\"\n              [(ngModel)]=\"model.selected\"\n              (onSearch)=\"onInput.next($event)\"\n              [displayProperty]=\"'version'\"\n              [required]=\"true\"\n              [hideNew]=\"true\"\n              [container]=\"'body'\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let version of versions$; loadMore: 'auto'; notFound: notFoundTemplate\"\n                (click)=\"onAppVersionSelect(version)\"\n                [active]=\"model.selected === version\"\n              >\n                <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n                <span\n                  [ngStyle]=\"{\n                    display: 'flex',\n                    'flex-direction': 'row',\n                    'align-content': 'center',\n                    'justify-content': 'space-between',\n                    'align-items': 'center'\n                  }\"\n                >\n                  <c8y-highlight\n                    [text]=\"version.version || '--'\"\n                    [pattern]=\"onInput | async\"\n                  ></c8y-highlight>\n\n                  <span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngFor=\"let tag of version.tags\"\n                    >\n                      {{ tag }}\n                    </span>\n                  </span>\n                </span>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li\n                  class=\"bg-gray-lighter p-8\"\n                  *ngIf=\"(onInput | async)?.length > 0 && (versions$ | async)?.data?.length === 0\"\n                >\n                  <span translate>No match found.</span>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        class=\"text-center d-block\"\n        [message]=\"'Installing\u2026' | translate\"\n        *ngIf=\"inProgress\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      class=\"d-flex a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n    >\n      <c8y-operation-result\n        class=\"lead\"\n        type=\"success\"\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n      ></c8y-operation-result>\n    </div>\n    <ng-template #failedDeploy>\n      <div\n        class=\"d-flex a-i-center j-c-center\"\n        style=\"min-height: 257px\"\n      >\n        <c8y-operation-result\n          class=\"lead\"\n          type=\"error\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ 'Back' | translate }}\"\n    type=\"button\"\n    *ngIf=\"!isDeployed\"\n    (click)=\"selectedPackage ? clean() : back()\"\n    [disabled]=\"inProgress\"\n  >\n    {{ 'Back' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\"\n    type=\"button\"\n    (click)=\"cancel()\"\n  >\n    {{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\n  </button>\n\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Install' | translate }}\"\n    type=\"button\"\n    (click)=\"deployApp()\"\n    [disabled]=\"inProgress || !packages?.length\"\n    *ngIf=\"!isDeployed\"\n  >\n    {{ 'Install' | translate }}\n  </button>\n</c8y-wizard-footer>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.ApplicationService }, { type: i3.WizardComponent }, { type: i3.PluginsService }], propDecorators: { applicationPropertiesForm: [{
                type: ViewChild,
                args: [ApplicationPropertiesFormComponent]
            }] } });
//# sourceMappingURL=data:application/json;base64, 