// Path: siden-core/src/main/java/ninja/siden/FilterChain.java
// @FunctionalInterface
// public interface FilterChain {
// 
// 	Object next() throws Exception;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/Request.java
// public interface Request extends AttributeContainer {
// 
// 	HttpMethod method();
// 
// 	String path();
// 
// 	/**
// 	 * get path parameter
// 	 * 
// 	 * @param key
// 	 * @return
// 	 */
// 	Optional<String> params(String key);
// 
// 	Map<String, String> params();
// 
// 	/**
// 	 * get query parameter
// 	 * 
// 	 * @param key
// 	 * @return
// 	 */
// 	Optional<String> query(String key);
// 
// 	Optional<String> header(String name);
// 
// 	List<String> headers(String name);
// 
// 	Map<String, List<String>> headers();
// 
// 	Map<String, Cookie> cookies();
// 
// 	Optional<Cookie> cookie(String name);
// 
// 	Optional<String> form(String key);
// 
// 	List<String> forms(String key);
// 
// 	Map<String, List<String>> forms();
// 
// 	Optional<File> file(String key);
// 
// 	List<File> files(String key);
// 
// 	Map<String, List<File>> files();
// 
// 	Optional<String> body();
// 
// 	/**
// 	 * get current session or create new session.
// 	 * 
// 	 * @return session
// 	 */
// 	Session session();
// 
// 	/**
// 	 * get current session
// 	 * 
// 	 * @return session or empty
// 	 */
// 	Optional<Session> current();
// 
// 	boolean xhr();
// 
// 	String protocol();
// 
// 	String scheme();
// 
// 	HttpServerExchange raw();
// 
// }
// 
// Path: siden-core/src/main/java/ninja/siden/Response.java
// public interface Response {
// 
// 	Response status(int code);
// 
// 	Response header(String name, String... values);
// 
// 	/**
// 	 * set RFC1123 date pattern to Response header.
// 	 * 
// 	 * @param name
// 	 * @param date
// 	 * @return this
// 	 */
// 	Response header(String name, long date);
// 
// 	Response headers(Map<String, String> headers);
// 
// 	Cookie cookie(String name, String value);
// 
// 	/**
// 	 * @param name
// 	 * @return existing value
// 	 */
// 	Cookie removeCookie(String name);
// 
// 	/**
// 	 * @param contentType
// 	 */
// 	Response type(String contentType);
// 
// 	Object redirect(String location);
// 
// 	Object redirect(int code, String location);
// 
// 	<MODEL> Object render(MODEL model, Renderer<MODEL> renderer);
// 
// 	<MODEL> Object render(MODEL model, String template);
// 
// 	HttpServerExchange raw();
// }
// 
// Path: siden-core/src/main/java/ninja/siden/def/FilterDef.java
// public class FilterDef implements Predicate, Filter {
// 
// 	final Predicate predicate;
// 
// 	final Filter filter;
// 
// 	public FilterDef(Predicate predicate, Filter filter) {
// 		this.predicate = Objects.requireNonNull(predicate);
// 		this.filter = Objects.requireNonNull(filter);
// 	}
// 
// 	@Override
// 	public boolean resolve(HttpServerExchange value) {
// 		return this.predicate.resolve(value);
// 	}
// 
// 	@Override
// 	public void filter(Request req, Response res, FilterChain chain)
// 			throws Exception {
// 		this.filter.filter(req, res, chain);
// 	}
// }


import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import java.util.ArrayList;
import java.util.List;
import ninja.siden.FilterChain;
import ninja.siden.Request;
import ninja.siden.Response;
import ninja.siden.def.FilterDef;
/*
 * Copyright 2014 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.internal;




/**
 * @author taichi
 */
public class FiltersHandler implements HttpHandler {

	HttpHandler next;

	List<FilterDef> filters = new ArrayList<>();

	public FiltersHandler(HttpHandler next) {
		this.next = next;
	}

	@Override
	public void handleRequest(HttpServerExchange exchange) throws Exception {
		if (filters.size() < 1) {
			next.handleRequest(exchange);
			return;
		}
		SimpleChain chain = new SimpleChain(exchange);
		chain.next();
	}

	public void add(FilterDef model) {
		this.filters.add(model);
	}

	enum ChainState {
		HasNext, NoMore;
	}

	class SimpleChain implements FilterChain {

		int cursor;

		HttpServerExchange exchange;

		Request request;

// Path: siden-core/src/main/java/ninja/siden/FilterChain.java
// @FunctionalInterface
// public interface FilterChain {
// 
// 	Object next() throws Exception;
// }
// 
// Path: siden-core/src/main/java/ninja/siden/Request.java
// public interface Request extends AttributeContainer {
// 
// 	HttpMethod method();
// 
// 	String path();
// 
// 	/**
// 	 * get path parameter
// 	 * 
// 	 * @param key
// 	 * @return
// 	 */
// 	Optional<String> params(String key);
// 
// 	Map<String, String> params();
// 
// 	/**
// 	 * get query parameter
// 	 * 
// 	 * @param key
// 	 * @return
// 	 */
// 	Optional<String> query(String key);
// 
// 	Optional<String> header(String name);
// 
// 	List<String> headers(String name);
// 
// 	Map<String, List<String>> headers();
// 
// 	Map<String, Cookie> cookies();
// 
// 	Optional<Cookie> cookie(String name);
// 
// 	Optional<String> form(String key);
// 
// 	List<String> forms(String key);
// 
// 	Map<String, List<String>> forms();
// 
// 	Optional<File> file(String key);
// 
// 	List<File> files(String key);
// 
// 	Map<String, List<File>> files();
// 
// 	Optional<String> body();
// 
// 	/**
// 	 * get current session or create new session.
// 	 * 
// 	 * @return session
// 	 */
// 	Session session();
// 
// 	/**
// 	 * get current session
// 	 * 
// 	 * @return session or empty
// 	 */
// 	Optional<Session> current();
// 
// 	boolean xhr();
// 
// 	String protocol();
// 
// 	String scheme();
// 
// 	HttpServerExchange raw();
// 
// }
// 
// Path: siden-core/src/main/java/ninja/siden/Response.java
// public interface Response {
// 
// 	Response status(int code);
// 
// 	Response header(String name, String... values);
// 
// 	/**
// 	 * set RFC1123 date pattern to Response header.
// 	 * 
// 	 * @param name
// 	 * @param date
// 	 * @return this
// 	 */
// 	Response header(String name, long date);
// 
// 	Response headers(Map<String, String> headers);
// 
// 	Cookie cookie(String name, String value);
// 
// 	/**
// 	 * @param name
// 	 * @return existing value
// 	 */
// 	Cookie removeCookie(String name);
// 
// 	/**
// 	 * @param contentType
// 	 */
// 	Response type(String contentType);
// 
// 	Object redirect(String location);
// 
// 	Object redirect(int code, String location);
// 
// 	<MODEL> Object render(MODEL model, Renderer<MODEL> renderer);
// 
// 	<MODEL> Object render(MODEL model, String template);
// 
// 	HttpServerExchange raw();
// }
// 
// Path: siden-core/src/main/java/ninja/siden/def/FilterDef.java
// public class FilterDef implements Predicate, Filter {
// 
// 	final Predicate predicate;
// 
// 	final Filter filter;
// 
// 	public FilterDef(Predicate predicate, Filter filter) {
// 		this.predicate = Objects.requireNonNull(predicate);
// 		this.filter = Objects.requireNonNull(filter);
// 	}
// 
// 	@Override
// 	public boolean resolve(HttpServerExchange value) {
// 		return this.predicate.resolve(value);
// 	}
// 
// 	@Override
// 	public void filter(Request req, Response res, FilterChain chain)
// 			throws Exception {
// 		this.filter.filter(req, res, chain);
// 	}
// }


// Path: siden-core/src/main/java/ninja/siden/internal/FiltersHandler.java
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import java.util.ArrayList;
import java.util.List;
import ninja.siden.FilterChain;
import ninja.siden.Request;
import ninja.siden.Response;
import ninja.siden.def.FilterDef;

/*
 * Copyright 2014 SATO taichi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ninja.siden.internal;




/**
 * @author taichi
 */
public class FiltersHandler implements HttpHandler {

	HttpHandler next;

	List<FilterDef> filters = new ArrayList<>();

	public FiltersHandler(HttpHandler next) {
		this.next = next;
	}

	@Override
	public void handleRequest(HttpServerExchange exchange) throws Exception {
		if (filters.size() < 1) {
			next.handleRequest(exchange);
			return;
		}
		SimpleChain chain = new SimpleChain(exchange);
		chain.next();
	}

	public void add(FilterDef model) {
		this.filters.add(model);
	}

	enum ChainState {
		HasNext, NoMore;
	}

	class SimpleChain implements FilterChain {

		int cursor;

		HttpServerExchange exchange;

		Request request;

		Response response;