/*
 * Copyright 2020 VMware, Inc. All rights reserved. VMware Confidential
 */
import { Observable, Subscription } from "rxjs";
import { ComponentCreatedData } from "../../../extensions/vdcs/resources/resources.component";
import { ExtensionComponentRegistration } from "../extension-component.registry";

export interface ExtensionPointContainer {
    /**
     * Define list of css selectors where the extension points
     * may be renderd.
     */
    readonly supportedLocations: SupportedLocation[];

    /**
     * Define the type of extension points which your component is supporting
     */
    readonly EXTENSION_POINT_TYPE: string;

    /**
     * Define the registry which will be used to orchestrate where
     * you want to render the extension points.
     */
    readonly extensionPointsRenderRegistry: {
        after: CssSelectorBasedExtensionPointRegistry;
        before: CssSelectorBasedExtensionPointRegistry;
    };

    /**
     * Define the list of wizard pages names, populated by each individual host component.
     */
    extensionNames?: {
        [urn: string]: string;
    };

    /**
     * Define method which will handle the extension point creation,
     * depends on the implementation details.
     */
    prepareExtensionPoints: (...args: any[]) => any;

    /**
     * Method which will handle the event after creating component dynamically
     *
     * @param extension - The component and all the metadata about the Extension Point,
     * which has been created.
     */
    handleComponentCreation: (extenson: ComponentCreatedData, ...args: any[]) => any;
}

export interface ExtensionPointContainerWithValidation extends ExtensionPointContainer {
    /**
     * List of all extensions form states, used to validate the Core UI form.
     */
    extensionStateRegister?: Observable<WizardExtensionState>[];

    /**
     * Flag, determining should the Core UI form to be marked as valid or invalid
     * based on the extensions form state.
     */
    allExtensionsAreValid?: boolean;

    /**
     * Subscription holder, used to unsubscribe when new extension point get
     * registered at runtime.
     */
    extensionStateSubscription?: Subscription;
}

export interface SupportedLocation {
    selector: string;
    before: boolean;
    after: boolean;
}

export interface CssSelectorBasedExtensionPointRegistry {
    [cssSelector: string]: ExtensionComponentRegistration[];
}

export abstract class WizardExtensionComponent<P, R, E> {
    /**
     * Define method which will be executed by the Extension Point Orchestrator,
     * when certain event is triggered.
     * @param payload - the payload of the request triggered by the Core UI.
     * @param response - the response from the request triggered by the Core UI.
     * @param error - the Core UI will reprot any error that may appear during execution.
     */
    abstract performAction(payload: P, response: R, error: E): void;
}

export interface WizardExtensionState {
    isValid: boolean;
}

export abstract class WizardExtensionWithValidationComponent<P, R, E> extends WizardExtensionComponent<P, R, E> {
    abstract getState(): Observable<WizardExtensionState>;
}