/*
 * Copyright 2012 gitblit.com.
 *
 * 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 com.gitblit.wicket;

import java.text.MessageFormat;

import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.protocol.http.WicketURLDecoder;
import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.apache.wicket.util.string.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.wicket.pages.BasePage;

/**
 * This class is used to create a stateless form that can POST or GET to a
 * bookmarkable page regardless of the pagemap and even after session expiration
 * or a server restart.
 *
 * The trick is to embed "wicket:bookmarkablePage" as a hidden field of the form.
 * Wicket already has logic to extract this parameter when it is trying
 * to determine which page should receive the request.
 *
 * The parameters of the containing page can optionally be included as hidden
 * fields in this form.  Note that if a page parameter's name collides with any
 * child's wicket:id in this form then the page parameter is excluded.
 *
 * @author James Moger
 *
 */
public class SessionlessForm<T> extends StatelessForm<T> {

	private static final long serialVersionUID = 1L;

	private static final String HIDDEN_DIV_START = "<div style=\"width:0px;height:0px;position:absolute;left:-100px;top:-100px;overflow:hidden\">";

	protected final Class<? extends BasePage> pageClass;

	protected final PageParameters pageParameters;

	private final Logger log = LoggerFactory.getLogger(SessionlessForm.class);

	/**
	 * Sessionless forms must have a bookmarkable page class.  A bookmarkable
	 * page is defined as a page that has only a default and/or a PageParameter
	 * constructor.
	 *
	 * @param id
	 * @param bookmarkablePageClass
	 */
	public SessionlessForm(String id, Class<? extends BasePage> bookmarkablePageClass) {
		this(id, bookmarkablePageClass, null);
	}

	/**
	 * Sessionless forms must have a bookmarkable page class.  A bookmarkable
	 * page is defined as a page that has only a default and/or a PageParameter
	 * constructor.
	 *
	 * @param id
	 * @param bookmarkablePageClass
	 * @param pageParameters
	 */
	public SessionlessForm(String id, Class<? extends BasePage> bookmarkablePageClass,
			PageParameters pageParameters) {
		super(id);
		this.pageClass = bookmarkablePageClass;
		this.pageParameters = pageParameters;
	}


	/**
	 * Append an additional hidden input tag that forces Wicket to correctly
	 * determine the destination page class even after a session expiration or
	 * a server restart.
	 *
	 * @param markupStream
	 *            The markup stream
	 * @param openTag
	 *            The open tag for the body
	 */
	@Override
	protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
	{
		// render the hidden bookmarkable page field
		AppendingStringBuffer buffer = new AppendingStringBuffer(HIDDEN_DIV_START);
		buffer.append("<input type=\"hidden\" name=\"")
			.append(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME)
			.append("\" value=\":")
			.append(pageClass.getName())
			.append("\" />");

		// insert the page parameters, if any, as hidden fields as long as they
		// do not collide with any child wicket:id of the form.
		if (pageParameters != null) {
			for (String key : pageParameters.keySet()) {
				Component c = get(key);
				if (c != null) {
					// this form has a field id which matches the
					// parameter name, skip embedding a hidden value
					log.warn(MessageFormat.format("Skipping page parameter \"{0}\" from sessionless form hidden fields because it collides with a form child wicket:id", key));
					continue;
				}
				String value = pageParameters.getString(key);
				buffer.append("<input type=\"hidden\" name=\"")
				.append(recode(key))
				.append("\" value=\"")
				.append(recode(value))
				.append("\" />");
			}
		}

		buffer.append("</div>");
		getResponse().write(buffer);
		super.onComponentTagBody(markupStream, openTag);
	}

	/**
	 * Take URL-encoded query string value, unencode it and return HTML-escaped version
	 *
	 * @param s
	 *            value to reencode
	 * @return reencoded value
	 */
	private String recode(String s) {
		String un = WicketURLDecoder.QUERY_INSTANCE.decode(s);
		return Strings.escapeMarkup(un).toString();
	}

	protected String getAbsoluteUrl() {
		return getAbsoluteUrl(pageClass, pageParameters);
	}

	protected String getAbsoluteUrl(Class<? extends BasePage> pageClass, PageParameters pageParameters) {
		String relativeUrl = urlFor(pageClass, pageParameters).toString();
		String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
		return absoluteUrl;
	}
}
