export interface ActivationItem {
    name: string;
    service: string;
}

/**
 * Contains information about the error which occurred during service activation.
 * 
 * Information about activation error includes original exception which has
 * occurred, the name of the service being activated and activation stack of
 * services.
 */
export class ActivationError {
    /**
     * Stack of services being activating
     */
    readonly activationStack: ActivationItem[];

    /**
     * The name of the failed service
     */
    readonly service: string;

    /**
     * The exception which occurred during activation of the service
     */
    readonly innerException: unknown;

    /**
     * Error message
     */
    readonly message: string;

    constructor(service: string, activationStack: ActivationItem[], innerException: unknown) {
        this.message = "Failed to activate the service";
        this.activationStack = activationStack;
        this.service = service;
        this.innerException = innerException;
    }

    toString() {
        const parts = [this.message];
        if (this.service)
            parts.push(`when activating: ${String(this.service)}`);

        if (this.innerException)
            parts.push(`caused by: ${String(this.innerException)}`);

        if (this.activationStack) {
            parts.push("at");
            parts.push.apply(null,
                this.activationStack
                    .map(({ name, service }) => `    ${name} ${service}`)
            );

        }

        return parts.join("\n");
    }
}
