package timely.netty.http;

import javax.net.ssl.SSLHandshakeException;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.response.TimelyException;

@Sharable
public class TimelyExceptionHandler extends SimpleChannelInboundHandler<TimelyException> implements TimelyHttpHandler {

    private static final Logger LOG = LoggerFactory.getLogger(TimelyExceptionHandler.class);
    private boolean ignoreSslHandshakeErrors = false;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TimelyException msg) throws Exception {
        this.sendHttpError(ctx, msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // ignore SSLHandshakeException when using a self-signed server certificate
        if (ignoreSslHandshakeErrors && cause.getCause() instanceof SSLHandshakeException) {
            return;
        }
        LOG.error("Unhandled exception in pipeline", cause);
        if (cause instanceof TimelyException) {
            this.sendHttpError(ctx, (TimelyException) cause);
        } else if (null != cause.getCause() && cause.getCause() instanceof TimelyException) {
            this.sendHttpError(ctx, (TimelyException) cause.getCause());
        } else {
            TimelyException e = new TimelyException(HttpResponseStatus.INTERNAL_SERVER_ERROR.code(), cause.getMessage(),
                    "");
            this.sendHttpError(ctx, e);
        }
    }

    public TimelyExceptionHandler setIgnoreSslHandshakeErrors(boolean ignoreSslHandshakeErrors) {
        this.ignoreSslHandshakeErrors = ignoreSslHandshakeErrors;
        return this;
    }
}