package com.lya.virtualis_stand.beans.rewrite;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ocpsoft.common.services.NonEnriching;
import org.ocpsoft.rewrite.config.Condition;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationLoader;
import org.ocpsoft.rewrite.config.Rule;
import org.ocpsoft.rewrite.config.RuleBuilder;
import org.ocpsoft.rewrite.context.RewriteState;
import org.ocpsoft.rewrite.param.DefaultParameterValueStore;
import org.ocpsoft.rewrite.param.ParameterValueStore;
import org.ocpsoft.rewrite.servlet.config.JAASRoles;
import org.ocpsoft.rewrite.servlet.config.rule.Join;
import org.ocpsoft.rewrite.servlet.event.BaseRewrite.ServletRewriteFlow;
import org.ocpsoft.rewrite.servlet.http.HttpRewriteProvider;
import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite;
import org.ocpsoft.rewrite.servlet.impl.EvaluationContextImpl;

public class RewriteProvider403 extends HttpRewriteProvider implements NonEnriching {

	private volatile ConfigurationLoader	loader;

	@Override
	public void init(final ServletContext context) {
		if (loader == null) {
			synchronized (this) {
				if (loader == null) {
					loader = ConfigurationLoader.create(context);
				}
			}
		}

		loader.loadConfiguration(context);
	}

	@Override
	public int priority() {
		return -1;
	}

	@Override
	public void rewriteHttp(final HttpServletRewrite event) {
		ServletContext servletContext = event.getServletContext();
		if (loader == null) {
			synchronized (servletContext) {
				if (loader == null) {
					loader = ConfigurationLoader.create(servletContext);
				}
			}
		}
		Configuration compiledConfiguration = loader.loadConfiguration(servletContext);
		List<Rule> rules = compiledConfiguration.getRules();

		final EvaluationContextImpl context = new EvaluationContextImpl();

		context.clear();
		DefaultParameterValueStore values = new DefaultParameterValueStore();
		context.put(ParameterValueStore.class, values);
		context.setState(RewriteState.EVALUATING);

		for (int i = 0; i < rules.size(); i++) {
			Rule rule = rules.get(i);
			if (rule instanceof RuleBuilder) {
				RuleBuilder rb = (RuleBuilder) rule;
				for (Condition cond1 : rb.getConditions()) {
					if (cond1 instanceof RuleBuilder) {
						RuleBuilder rb1 = (RuleBuilder) cond1;
						boolean goodPath = false;
						for (Condition cond2 : rb1.getConditions()) {
							if (cond2 instanceof Join) {
								Join join = (Join) cond2;
								goodPath = join.evaluate(event, context);
							}
							if (goodPath && cond2 instanceof JAASRoles) {
								JAASRoles roles = (JAASRoles) cond2;
								if (!roles.evaluate(event, context)) {
									try {
										HttpServletRequest req = event.getRequest();
										HttpServletResponse resp = event.getResponse();
										resp.sendRedirect(req.getContextPath() + "/login");
										// resp.sendError(403);
										// event.setFlow(ServletRewriteFlow.ABORT_REQUEST);
										event.setFlow(ServletRewriteFlow.REDIRECT_PERMANENT);
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
						}
					}
				}
			}
		}
	}

	@Override
	public void shutdown(final ServletContext context) {
	}

}
