/*
 * Copyright 2011 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.pages;

import java.util.List;

import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

import com.gitblit.servlet.RawServlet;
import com.gitblit.utils.BugtraqProcessor;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.MarkupProcessor;
import com.gitblit.wicket.MarkupProcessor.MarkupDocument;
import com.gitblit.wicket.MarkupProcessor.MarkupSyntax;
import com.gitblit.wicket.WicketUtils;

@CacheControl(LastModified.BOOT)
public class DocPage extends RepositoryPage {

	public DocPage(PageParameters params) {
		super(params);

		final String path = WicketUtils.getPath(params).replace("%2f", "/").replace("%2F", "/");
		MarkupProcessor processor = new MarkupProcessor(app().settings(), app().xssFilter());

		Repository r = getRepository();
		RevCommit commit = JGitUtils.getCommit(r, objectId);
		String [] encodings = getEncodings();

		// Read raw markup content and transform it to html
		String documentPath = path;
		String markupText = JGitUtils.getStringContent(r, commit.getTree(), path, encodings);

		// Hunt for document
		if (StringUtils.isEmpty(markupText)) {
			String name = StringUtils.stripFileExtension(path);

			List<String> docExtensions = processor.getAllExtensions();
			for (String ext : docExtensions) {
				String checkName = name + "." + ext;
				markupText = JGitUtils.getStringContent(r, commit.getTree(), checkName, encodings);
				if (!StringUtils.isEmpty(markupText)) {
					// found it
					documentPath = path;
					break;
				}
			}
		}

		if (markupText == null) {
			markupText = "";
		}

		BugtraqProcessor bugtraq = new BugtraqProcessor(app().settings());
		markupText = bugtraq.processText(getRepository(), repositoryName, markupText);

		Fragment fragment;
		MarkupDocument markupDoc = processor.parse(repositoryName, getBestCommitId(commit), documentPath, markupText);
		if (MarkupSyntax.PLAIN.equals(markupDoc.syntax)) {
			fragment = new Fragment("doc", "plainContent", this);
		} else {
			fragment = new Fragment("doc", "markupContent", this);
		}

		// document page links
		fragment.add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class,
				WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));
		fragment.add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class,
				WicketUtils.newPathParameter(repositoryName, objectId, documentPath)));
		String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, documentPath);
		fragment.add(new ExternalLink("rawLink", rawUrl));

		fragment.add(new Label("content", markupDoc.html).setEscapeModelStrings(false));
		add(fragment);
	}

	@Override
	protected String getPageName() {
		return getString("gb.docs");
	}

	@Override
	protected boolean isCommitPage() {
		return true;
	}

	@Override
	protected Class<? extends BasePage> getRepoNavPageClass() {
		return DocsPage.class;
	}
}
