/* tslint:disable */
/* eslint-disable */
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
import type { TsoaRoute } from '@tsoa/runtime';
import { fetchMiddlewares, HapiTemplateService } from '@tsoa/runtime';
{{#each controllers}}
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
import { {{name}} } from '{{modulePath}}';
{{/each}}
{{#if authenticationModule}}
import { hapiAuthentication } from '{{authenticationModule}}';
// @ts-ignore - no great way to install types from subpackage
{{/if}}
{{#if iocModule}}
import { iocContainer } from '{{iocModule}}';
import type { IocContainer, IocContainerFactory } from '@tsoa/runtime';
{{/if}}
import { boomify, isBoom, type Payload } from '@hapi/boom';
import type { Request, ResponseToolkit, RouteOptionsPreAllOptions } from '@hapi/hapi';

// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

const models: TsoaRoute.Models = {
    {{#each models}}
    "{{@key}}": {
        {{#if enums}}
        "dataType": "refEnum",
        "enums": {{{json enums}}},
        {{/if}}
        {{#if properties}}
        "dataType": "refObject",
        "properties": {
            {{#each properties}}
            "{{@key}}": {{{json this}}},
            {{/each}}
        },
        "additionalProperties": {{{json additionalProperties}}},
        {{/if}}
        {{#if type}}
        "dataType": "refAlias",
        "type": {{{json type}}},
        {{/if}}
    },
    // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
    {{/each}}
};
const templateService = new HapiTemplateService(
  models,
  {{{ json minimalSwaggerConfig }}},
  { boomify, isBoom },
);

// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

export function RegisterRoutes(server: any) {
    // ###########################################################################################################
    //  NOTE: If you do not see routes for all of your controllers in this file, then you might not have informed tsoa of where to look
    //      Please look into the "controllerPathGlobs" config option described in the readme: https://github.com/lukeautry/tsoa
    // ###########################################################################################################
    {{#each controllers}}
    {{#each actions}}
        const args{{../name}}_{{name}}: Record<string, TsoaRoute.ParameterSchema> = {
          {{#each parameters}}
            {{@key}}: {{{json this}}},
          {{/each}}
        };
        server.route({
            method: '{{method}}',
            path: '{{fullPath}}',
            options: {
                pre: [
                    {{#if security.length}}
                    {
                      method: authenticateMiddleware({{json security}})
                    },
                    {{/if}}
                    {{#if uploadFile}}
                      {{#each uploadFileName}}
                    {
                      {{#if multiple}}
                      method: fileUploadMiddleware('{{name}}', true)
                      {{else}}
                      method: fileUploadMiddleware('{{name}}', false)
                      {{/if}}
                    },
                      {{/each}}
                    {{/if}}
                    ...(fetchMiddlewares<RouteOptionsPreAllOptions>({{../name}})),
                    ...(fetchMiddlewares<RouteOptionsPreAllOptions>({{../name}}.prototype.{{name}})),
                ],
                {{#if uploadFile}}
                payload: {
                  output: 'stream',
                  parse: true,
                  multipart: true,
                  allow: 'multipart/form-data'
                },
                {{/if}}
                handler: {{#if ../../iocModule}}async {{/if}}function {{../name}}_{{name}}(request: Request, h: ResponseToolkit) {

                    let validatedArgs: any[] = [];
                    try {
                        validatedArgs = templateService.getValidatedArgs({ args: args{{../name}}_{{name}}, request, h });
                    } catch (err) {
                        const error = err as any;
                        if (isBoom(error)) {
                            throw error;
                        }

                        const boomErr = boomify(error instanceof Error ? error : new Error(error.message), { statusCode: error.status || 500 });
                        boomErr.output.statusCode = error.status || 500;
                        boomErr.output.payload = {
                            name: error.name,
                            fields: error.fields,
                            message: error.message,
                        } as unknown as Payload;
                        throw boomErr;
                    }

                    {{#if ../../iocModule}}
                    const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer;

                    const controller: any = await container.get<{{../name}}>({{../name}});
                    if (typeof controller['setStatus'] === 'function') {
                        controller.setStatus(undefined);
                    }
                    {{else}}
                    const controller = new {{../name}}();
                    {{/if}}

                    return templateService.apiHandler({
                      methodName: '{{name}}',
                      controller,
                      h,
                      validatedArgs,
                      successStatus: {{successStatus}},
                    });
                }
            }
        });
        // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
    {{/each}}
    {{/each}}

    {{#if useSecurity}}

    // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

    function authenticateMiddleware(security: TsoaRoute.Security[] = []) {
        return async function runAuthenticationMiddleware(request: any, h: any) {

            // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

            // keep track of failed auth attempts so we can hand back the most
            // recent one.  This behavior was previously existing so preserving it
            // here
            const failedAttempts: any[] = [];
            const pushAndRethrow = (error: any) => {
                failedAttempts.push(error);
                throw error;
            };

            const secMethodOrPromises: Promise<any>[] = [];
            for (const secMethod of security) {
                if (Object.keys(secMethod).length > 1) {
                    const secMethodAndPromises: Promise<any>[] = [];

                    for (const name in secMethod) {
                        secMethodAndPromises.push(
                            hapiAuthentication(request, name, secMethod[name])
                                .catch(pushAndRethrow)
                        );
                    }

                    // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

                    secMethodOrPromises.push(Promise.all(secMethodAndPromises)
                        .then(users => { return users[0]; }));
                } else {
                    for (const name in secMethod) {
                        secMethodOrPromises.push(
                            hapiAuthentication(request, name, secMethod[name])
                                .catch(pushAndRethrow)
                        );
                    }
                }
            }

            // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa

            try {
                request['user'] = await Promise.any(secMethodOrPromises);
                return request['user'];
            }
            catch(err) {
                // Show most recent error as response
                const error = failedAttempts.pop();
                if (isBoom(error)) {
                    throw error;
                }

                const boomErr = boomify(error instanceof Error ? error : new Error(error.message), { statusCode: error.status || 500 });
                boomErr.output.statusCode = error.status || 401;
                boomErr.output.payload = {
                    name: error.name,
                    message: error.message,
                } as unknown as Payload;

                throw boomErr;
            }

            // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
        }
    }
    {{/if}}

    {{#if useFileUploads}}
    function fileUploadMiddleware(fieldname: string, multiple: boolean = false) {
      return (request: Request, h: any) => {
        if (!request.payload[fieldname]) {
          return h.response(`${fieldname} is a required file(s).`).code(400);
        }

        const calculateFileInfo = (reqFile: any) => new Promise((resolve, reject) => {
          const originalname = reqFile.hapi.filename;
          const headers = reqFile.hapi.headers;
          const contentTransferEncoding = headers['content-transfer-encoding'];
          const encoding = contentTransferEncoding &&
            contentTransferEncoding[0] &&
            contentTransferEncoding[0].toLowerCase() || '7bit';
          const mimetype = headers['content-type'] || 'text/plain';
          const buffer = reqFile._data
          return resolve({
            fieldname,
            originalname,
            buffer,
            encoding,
            mimetype,
            filename: originalname,
            size: buffer.toString().length,
          })
        });

        if (!multiple) {
          return calculateFileInfo(request.payload[fieldname])
            .then(fileMetadata => {
              request.payload[fieldname] = fileMetadata;
              return h.continue;
            })
            .catch(err => h.response(err.toString()).code(500));
        } else {
          const promises = request.payload[fieldname].map((reqFile: any) => calculateFileInfo(reqFile));
          return Promise.all(promises)
            .then(filesMetadata => {
              request.payload[fieldname] = filesMetadata;
              return h.continue;
            })
            .catch(err => h.response(err.toString()).code(500));
        }
      };
    }
    {{/if}}

    // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
}

// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
