"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetupHttpHandler = void 0;
const OkResponseDescription_1 = require("../../http/output/response/OkResponseDescription");
const BasicRepresentation_1 = require("../../http/representation/BasicRepresentation");
const LogUtil_1 = require("../../logging/LogUtil");
const OperationHttpHandler_1 = require("../../server/OperationHttpHandler");
const ContentTypes_1 = require("../../util/ContentTypes");
const MethodNotAllowedHttpError_1 = require("../../util/errors/MethodNotAllowedHttpError");
/**
 * Handles the initial setup of a server.
 * Will capture all requests until setup is finished,
 * this to prevent accidentally running unsafe servers.
 *
 * GET requests will return the view template which should contain the setup information for the user.
 * POST requests will be sent to the InteractionHandler.
 * After successfully completing a POST request this handler will disable itself and become unreachable.
 * All other methods will be rejected.
 */
class SetupHttpHandler extends OperationHttpHandler_1.OperationHttpHandler {
    constructor(args) {
        super();
        this.logger = (0, LogUtil_1.getLoggerFor)(this);
        this.handler = args.handler;
        this.converter = args.converter;
        this.storageKey = args.storageKey;
        this.storage = args.storage;
        this.templateEngine = args.templateEngine;
        this.allowRootPod = args.allowRootPod ?? true;
    }
    async handle({ operation }) {
        switch (operation.method) {
            case 'GET': return this.handleGet(operation);
            case 'POST': return this.handlePost(operation);
            default: throw new MethodNotAllowedHttpError_1.MethodNotAllowedHttpError([operation.method]);
        }
    }
    /**
     * Returns the HTML representation of the setup page.
     */
    async handleGet(operation) {
        const result = await this.templateEngine.handleSafe({ contents: { allowRootPod: this.allowRootPod } });
        const representation = new BasicRepresentation_1.BasicRepresentation(result, operation.target, ContentTypes_1.TEXT_HTML);
        return new OkResponseDescription_1.OkResponseDescription(representation.metadata, representation.data);
    }
    /**
     * Converts the input data to JSON and calls the setup handler.
     * On success `true` will be written to the storage key.
     */
    async handlePost(operation) {
        // Convert input data to JSON
        // Allows us to still support form data
        if (operation.body.metadata.contentType) {
            const args = {
                representation: operation.body,
                preferences: { type: { [ContentTypes_1.APPLICATION_JSON]: 1 } },
                identifier: operation.target,
            };
            operation = {
                ...operation,
                body: await this.converter.handleSafe(args),
            };
        }
        const representation = await this.handler.handleSafe({ operation });
        await this.storage.set(this.storageKey, true);
        return new OkResponseDescription_1.OkResponseDescription(representation.metadata, representation.data);
    }
}
exports.SetupHttpHandler = SetupHttpHandler;
//# sourceMappingURL=SetupHttpHandler.js.map