import { HttpProject } from '../models/HttpProject.js';
import { StoreSdk } from '../sdk/StoreSdkNode.js';
import { ProjectSerialRunner } from '../runtime/node/ProjectSerialRunner.js';
import { ProjectParallelRunner } from '../runtime/node/ProjectParallelRunner.js';
import Proxy from './Proxy.js';
import { Exception } from '../exceptions/exception.js';
/**
 * Runs requests from an HTTP project read from the store.
 */
export default class HttpProjectProxy extends Proxy {
    project;
    options;
    async configureStore(init, token, baseUri) {
        const { pid, options, organization } = init;
        const INVALID_REQUEST = 'Invalid request';
        const code = 'E_INVALID_REQUEST';
        if (!pid) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The "pid" parameter is required.',
                status: 400,
                code,
            });
        }
        if (!organization) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The "organization" parameter is required.',
                status: 400,
                code,
            });
        }
        if (!options) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The "options" parameter is required.',
                status: 400,
                code,
            });
        }
        if (!token) {
            throw new Exception(INVALID_REQUEST, {
                help: 'Set the authentication credentials.',
                status: 400,
                code,
            });
        }
        if (!baseUri) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The store uri is missing.',
                status: 400,
                code,
            });
        }
        if (!baseUri.startsWith('http')) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The store uri is invalid.',
                status: 400,
                code,
            });
        }
        const sdk = new StoreSdk(baseUri);
        sdk.token = token;
        let project;
        try {
            const data = await sdk.file.readMedia(organization, pid);
            project = data.media;
        }
        catch (cause) {
            const e = cause;
            throw new Exception(e.message, { status: 400 });
        }
        if (project.key !== pid) {
            throw new Exception(`Unable to read the project.`, { status: 500 });
        }
        this.options = options;
        this.project = new HttpProject(project);
    }
    async configureProject(init) {
        const { project, options } = init;
        const INVALID_REQUEST = 'Invalid request';
        const code = 'E_INVALID_REQUEST';
        if (!options) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The "options" parameter is required.',
                status: 400,
                code,
            });
        }
        if (!project) {
            throw new Exception(INVALID_REQUEST, {
                help: 'The "project" parameter is required.',
                status: 400,
                code,
            });
        }
        this.options = options;
        this.project = new HttpProject(project);
    }
    async configure(init, token, baseUri) {
        const typedStore = init;
        if (typeof typedStore.pid === 'string') {
            return this.configureStore(typedStore, token, baseUri);
        }
        const typedProject = init;
        return this.configureProject(typedProject);
    }
    async execute() {
        const project = this.project;
        const opts = this.options;
        let factory;
        if (opts.parallel) {
            factory = new ProjectParallelRunner(project, opts);
        }
        else {
            factory = new ProjectSerialRunner();
            factory.configure(project, opts);
        }
        function unhandledRejection() {
            //
        }
        // the executing library handles all related errors it need.
        // However, when executing a request to an unknown host Node process may
        // throw unhandled error event when the error is properly reported by the
        // application. This suppresses these errors.
        // Note, uncomment this line for debug.
        process.on('unhandledRejection', unhandledRejection);
        const report = await factory.execute();
        process.off('unhandledRejection', unhandledRejection);
        return {
            result: report,
        };
    }
}
//# sourceMappingURL=HttpProjectProxy.js.map