/*
 * Copyright 2017-2022 VMware, Inc. All rights reserved. VMware Confidential
 */

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { of, Observable, throwError as _throw } from "rxjs";
import { catchError, map, tap } from "rxjs/operators";
import { ExtensionManifest } from "../../extensibility.model";
import { ExtensionLoaderStep, ExternalExtensionLoaderState } from "../extension-loader.model";
import { ExternalExtensionLoaderErrorObservable } from "./external-extension-loader-error";

export const PLUGIN_MANIFEST_URL = "/manifest.json";

@Injectable()
export class LoadExternalExtensionManifestStep implements ExtensionLoaderStep<ExternalExtensionLoaderState> {
    constructor(private http: HttpClient) {}

    /**
     * Load an extension's manifest from {extensionRoot}/manifest.json.
     * State inputs: spec
     * State outputs: manifest
     */
    public perform(state: ExternalExtensionLoaderState): Observable<ExternalExtensionLoaderState> {
        try {
            const i18nManifestFile = state.spec.resourcePath + PLUGIN_MANIFEST_URL;
            console.log(`[${state.spec.id}] Loading extension manifest from: ${i18nManifestFile}`);
            return this.http.get<ExtensionManifest>(i18nManifestFile).pipe(
                tap((manifest: ExtensionManifest) =>
                    console.log(`[${state.spec.id} (${manifest.name})] Manifest loaded`, manifest)
                ),

                map((manifest) => ({ ...state, manifest })),
                catchError((err, caught) => {
                    console.error(`[${state?.spec?.id}] Could not load manifest`, err);
                    return of({ ...state });
                })
            );
        } catch (err) {
            console.error(`[${state?.spec?.id}] Could not load manifest`, err);
            return new ExternalExtensionLoaderErrorObservable();
        }
    }
}
