import { TwirpServer, TwirpError, TwirpErrorCode, TwirpContentType, chainInterceptors, } from 'twirp-ts';
import { StartJourneyRequest, StartJourneyResponse, JourneyProgressRequest, JourneyProgressResponse, JourneyInteractionRequest, JourneyInteractionResponse, EndJourneyRequest, EndJourneyResponse, } from './telemetry.js';
export var TelemetryPluginMethod;
(function (TelemetryPluginMethod) {
    TelemetryPluginMethod["StartJourney"] = "StartJourney";
    TelemetryPluginMethod["JourneyProgress"] = "JourneyProgress";
    TelemetryPluginMethod["JourneyInteraction"] = "JourneyInteraction";
    TelemetryPluginMethod["EndJourney"] = "EndJourney";
})(TelemetryPluginMethod || (TelemetryPluginMethod = {}));
export const TelemetryPluginMethodList = [
    TelemetryPluginMethod.StartJourney,
    TelemetryPluginMethod.JourneyProgress,
    TelemetryPluginMethod.JourneyInteraction,
    TelemetryPluginMethod.EndJourney,
];
export function createTelemetryPluginServer(service) {
    return new TwirpServer({
        service,
        packageName: 'devvit.plugin.telemetry',
        serviceName: 'TelemetryPlugin',
        methodList: TelemetryPluginMethodList,
        matchRoute: matchTelemetryPluginRoute,
    });
}
function matchTelemetryPluginRoute(method, events) {
    switch (method) {
        case 'StartJourney':
            return async (ctx, service, data, interceptors) => {
                ctx = { ...ctx, methodName: 'StartJourney' };
                await events.onMatch(ctx);
                return handleTelemetryPluginStartJourneyRequest(ctx, service, data, interceptors);
            };
        case 'JourneyProgress':
            return async (ctx, service, data, interceptors) => {
                ctx = { ...ctx, methodName: 'JourneyProgress' };
                await events.onMatch(ctx);
                return handleTelemetryPluginJourneyProgressRequest(ctx, service, data, interceptors);
            };
        case 'JourneyInteraction':
            return async (ctx, service, data, interceptors) => {
                ctx = { ...ctx, methodName: 'JourneyInteraction' };
                await events.onMatch(ctx);
                return handleTelemetryPluginJourneyInteractionRequest(ctx, service, data, interceptors);
            };
        case 'EndJourney':
            return async (ctx, service, data, interceptors) => {
                ctx = { ...ctx, methodName: 'EndJourney' };
                await events.onMatch(ctx);
                return handleTelemetryPluginEndJourneyRequest(ctx, service, data, interceptors);
            };
        default:
            events.onNotFound();
            const msg = `no handler found`;
            throw new TwirpError(TwirpErrorCode.BadRoute, msg);
    }
}
function handleTelemetryPluginStartJourneyRequest(ctx, service, data, interceptors) {
    switch (ctx.contentType) {
        case TwirpContentType.JSON:
            return handleTelemetryPluginStartJourneyJSON(ctx, service, data, interceptors);
        case TwirpContentType.Protobuf:
            return handleTelemetryPluginStartJourneyProtobuf(ctx, service, data, interceptors);
        default:
            const msg = 'unexpected Content-Type';
            throw new TwirpError(TwirpErrorCode.BadRoute, msg);
    }
}
function handleTelemetryPluginJourneyProgressRequest(ctx, service, data, interceptors) {
    switch (ctx.contentType) {
        case TwirpContentType.JSON:
            return handleTelemetryPluginJourneyProgressJSON(ctx, service, data, interceptors);
        case TwirpContentType.Protobuf:
            return handleTelemetryPluginJourneyProgressProtobuf(ctx, service, data, interceptors);
        default:
            const msg = 'unexpected Content-Type';
            throw new TwirpError(TwirpErrorCode.BadRoute, msg);
    }
}
function handleTelemetryPluginJourneyInteractionRequest(ctx, service, data, interceptors) {
    switch (ctx.contentType) {
        case TwirpContentType.JSON:
            return handleTelemetryPluginJourneyInteractionJSON(ctx, service, data, interceptors);
        case TwirpContentType.Protobuf:
            return handleTelemetryPluginJourneyInteractionProtobuf(ctx, service, data, interceptors);
        default:
            const msg = 'unexpected Content-Type';
            throw new TwirpError(TwirpErrorCode.BadRoute, msg);
    }
}
function handleTelemetryPluginEndJourneyRequest(ctx, service, data, interceptors) {
    switch (ctx.contentType) {
        case TwirpContentType.JSON:
            return handleTelemetryPluginEndJourneyJSON(ctx, service, data, interceptors);
        case TwirpContentType.Protobuf:
            return handleTelemetryPluginEndJourneyProtobuf(ctx, service, data, interceptors);
        default:
            const msg = 'unexpected Content-Type';
            throw new TwirpError(TwirpErrorCode.BadRoute, msg);
    }
}
async function handleTelemetryPluginStartJourneyJSON(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        const body = JSON.parse(data.toString() || '{}');
        request = StartJourneyRequest.fromJSON(body);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the json request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.StartJourney(ctx, inputReq);
        });
    }
    else {
        response = await service.StartJourney(ctx, request);
    }
    return JSON.stringify(StartJourneyResponse.toJSON(response));
}
async function handleTelemetryPluginJourneyProgressJSON(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        const body = JSON.parse(data.toString() || '{}');
        request = JourneyProgressRequest.fromJSON(body);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the json request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.JourneyProgress(ctx, inputReq);
        });
    }
    else {
        response = await service.JourneyProgress(ctx, request);
    }
    return JSON.stringify(JourneyProgressResponse.toJSON(response));
}
async function handleTelemetryPluginJourneyInteractionJSON(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        const body = JSON.parse(data.toString() || '{}');
        request = JourneyInteractionRequest.fromJSON(body);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the json request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.JourneyInteraction(ctx, inputReq);
        });
    }
    else {
        response = await service.JourneyInteraction(ctx, request);
    }
    return JSON.stringify(JourneyInteractionResponse.toJSON(response));
}
async function handleTelemetryPluginEndJourneyJSON(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        const body = JSON.parse(data.toString() || '{}');
        request = EndJourneyRequest.fromJSON(body);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the json request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.EndJourney(ctx, inputReq);
        });
    }
    else {
        response = await service.EndJourney(ctx, request);
    }
    return JSON.stringify(EndJourneyResponse.toJSON(response));
}
async function handleTelemetryPluginStartJourneyProtobuf(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        request = StartJourneyRequest.decode(data);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the protobuf request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.StartJourney(ctx, inputReq);
        });
    }
    else {
        response = await service.StartJourney(ctx, request);
    }
    return Buffer.from(StartJourneyResponse.encode(response).finish());
}
async function handleTelemetryPluginJourneyProgressProtobuf(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        request = JourneyProgressRequest.decode(data);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the protobuf request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.JourneyProgress(ctx, inputReq);
        });
    }
    else {
        response = await service.JourneyProgress(ctx, request);
    }
    return Buffer.from(JourneyProgressResponse.encode(response).finish());
}
async function handleTelemetryPluginJourneyInteractionProtobuf(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        request = JourneyInteractionRequest.decode(data);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the protobuf request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.JourneyInteraction(ctx, inputReq);
        });
    }
    else {
        response = await service.JourneyInteraction(ctx, request);
    }
    return Buffer.from(JourneyInteractionResponse.encode(response).finish());
}
async function handleTelemetryPluginEndJourneyProtobuf(ctx, service, data, interceptors) {
    let request;
    let response;
    try {
        request = EndJourneyRequest.decode(data);
    }
    catch (e) {
        if (e instanceof Error) {
            const msg = 'the protobuf request could not be decoded';
            throw new TwirpError(TwirpErrorCode.Malformed, msg).withCause(e, true);
        }
    }
    if (interceptors && interceptors.length > 0) {
        const interceptor = chainInterceptors(...interceptors);
        response = await interceptor(ctx, request, (ctx, inputReq) => {
            return service.EndJourney(ctx, inputReq);
        });
    }
    else {
        response = await service.EndJourney(ctx, request);
    }
    return Buffer.from(EndJourneyResponse.encode(response).finish());
}
