/*
 * 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 lc.mecha.fabric.HandlerStatus;
import lc.mecha.fabric.MessageReceiver;
import lc.mecha.log.MechaLogger;
import lc.mecha.log.MechaLoggerFactory;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by cal on 10/17/16.
 */
public abstract class PathHandler implements MessageReceiver<HttpTransaction> {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(PathHandler.class);
    private final Set<String> pathPrefix = new HashSet<>();

    public PathHandler(final Set<String> pathPrefixes) {
        logger.debug("PrefixHandler(): Creating new handler. [prefix: {}] [obj: {}]", pathPrefixes, this);
        this.pathPrefix.addAll(pathPrefixes);
    }

    public Set<String> getPathPrefix() {
        return pathPrefix;
    }

    @Override
    public HandlerStatus receive(final HttpTransaction request) throws Throwable {
        if (request.request.isHandled()) {
            logger.trace("Request already served. Bypassing.");
            return HandlerStatus.CONTINUE;
        }

        for (String path : pathPrefix) {
            logger.trace("Matching: {} to {}", path, request.httpServletRequest.getPathInfo());
            if (request.httpServletRequest.getPathInfo().equals(path)) {
                final HandlerStatus status = handlePrefixedWebRequest(request);
                if (status == HandlerStatus.BREAK)
                    request.request.setHandled(true);
                return status;
            }
        }

        logger.debug("Paths did not match, returning. [pathPrefix: {}] [pathInfo: {}]", pathPrefix,
                request.httpServletRequest.getPathInfo());

        return HandlerStatus.CONTINUE;
    }

    /**
     * Implement this method to handle the provided request. If any sort of error returns,
     * throw an exception and an error response will automatically be generated.
     *
     * @param request
     * @return
     * @throws Throwable
     */
    public abstract HandlerStatus handlePrefixedWebRequest(HttpTransaction request) throws Throwable;
}
