/*
 * Copyright (c) 2004-2017, by Alex Leigh.
 * All rights reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE
 * The copyright notice above does not evidence any
 * actual or intended publication of such source code.
 */

package lc.mecha.http.server;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lc.mecha.fabric.MessageFabric;
import lc.mecha.fabric.SynchronousFabric;
import lc.mecha.log.MechaLogger;
import lc.mecha.log.MechaLoggerFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import java.io.IOException;

/**
 * Implements a web processing pipeline.
 *
 * @author Alex Leigh
 */
public final class HttpPipeline extends AbstractHandler {
    public final static String KEY_SERVICE = "service";
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(HttpPipeline.class);
    private final MessageFabric<HttpTransaction> servicePipeline = new SynchronousFabric<>();

    public MessageFabric<HttpTransaction> getServicePipeline() {
        return servicePipeline;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final HttpPipeline that = (HttpPipeline) o;

        return servicePipeline != null ? servicePipeline.equals(that.servicePipeline) : that.servicePipeline == null;
    }

    @Override
    public int hashCode() {
        return servicePipeline != null ? servicePipeline.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "WebPipeline{" +
                "servicePipeline=" + servicePipeline +
                '}';
    }

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest
            httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        final HttpTransaction wr = new HttpTransaction(baseRequest, httpServletRequest, httpServletResponse);
        logger.debug("handle(): Received web request: {}", wr);
        try {
            servicePipeline.send(KEY_SERVICE, wr);
        } catch (Throwable e) {
            logger.warn("Handler threw", e);
            try {
                httpServletResponse.sendError(500);
            } catch (IOException e1) {
                logger.warn("Attempted to return an error 500 page, but failed: {}", e1);
            }
        }
    }
}
