/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.commons.logging.config;

/**
 * $Id$
 * @author afries
 * @date   Jan 18, 2016 10:09:23 AM
 *
 * Copyright (C) 2016 Scytl Secure Electronic Voting SA
 *
 * All rights reserved.
 *
 */

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.products.ov.commons.beans.domain.model.platform.LoggingInitializationState;



/**
 * Configurable filter that can filter requests to a number (configurable list) of services.
 * <P>
 */
public abstract class LoggingFilter implements Filter {

    private static final Logger LOG = LoggerFactory.getLogger("std");

    private static final String PART_OF_LOGGING_REQUEST = "/platformdata/";

    private static final String PART_OF_CHECK_RESOURCE = "/check";

    /**
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {

        LOG.info("Initializing filter - name: " + filterConfig.getFilterName() + ", path: "
            + filterConfig.getServletContext().getContextPath() + ", container: "
            + filterConfig.getServletContext().getServerInfo());
    }
    
    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
            throws IOException, ServletException {

        String uri;
        if (request instanceof HttpServletRequest) {
            uri = ((HttpServletRequest) request).getRequestURI();
        } else {
            LOG.info("The request is not a HttpServletRequest. Aborting");
            return;
        }

        HttpServletResponse httpServletResponse;
        if (response instanceof HttpServletResponse) {
            httpServletResponse = (HttpServletResponse) response;
        } else {
            LOG.info("The response is not the expected type. Expected a HttpServletResponse. Aborting.");
            return;
        }

        if (getLoggingInitializationState().getInitialized()) {

            filterChain.doFilter(request, response);
            return;

        } else if (uri.contains(PART_OF_LOGGING_REQUEST)) {

            LOG.info("Install platform request received");

            filterChain.doFilter(request, response);
            return;

        } else if (uri.contains(PART_OF_CHECK_RESOURCE)) {

            LOG.info("Forwarding to check health resource");
            filterChain.doFilter(request, response);
            return;

        } else {

            LOG.info("Request aborted as logging system not initialized");

            httpServletResponse.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode());
            return;
        }

    }
    
    @Override
    public void destroy() {
        LOG.info(filterName() + " - destroying filter");
    }

    public abstract LoggingInitializationState getLoggingInitializationState();
    
    public abstract String filterName();
}

