/*
 * Copyright 2014 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.panels;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Keys;
import com.gitblit.models.RepositoryModel;
import com.gitblit.wicket.WicketUtils;

/**
 * A radio group panel of the 5 available authorization/access restriction combinations.
 *
 * @author James Moger
 *
 */
public class AccessPolicyPanel extends BasePanel {

	private static final long serialVersionUID = 1L;

	private final RepositoryModel repository;

	private final AjaxFormChoiceComponentUpdatingBehavior callback;

	private RadioGroup<AccessPolicy> policiesGroup;

	private IModel<Boolean> allowForks;

	public AccessPolicyPanel(String wicketId, RepositoryModel repository) {
		this(wicketId, repository, null);
	}

	public AccessPolicyPanel(String wicketId, RepositoryModel repository, AjaxFormChoiceComponentUpdatingBehavior callback) {
		super(wicketId);
		this.repository = repository;
		this.callback = callback;
	}

	@Override
	protected void onInitialize() {
		super.onInitialize();

		AccessPolicy anonymousPolicy = new AccessPolicy(getString("gb.anonymousPolicy"),
				getString("gb.anonymousPolicyDescription"),
				"blank.png",
				AuthorizationControl.AUTHENTICATED,
				AccessRestrictionType.NONE);

		AccessPolicy authenticatedPushPolicy = new AccessPolicy(getString("gb.authenticatedPushPolicy"),
				getString("gb.authenticatedPushPolicyDescription"),
				"lock_go_16x16.png",
				AuthorizationControl.AUTHENTICATED,
				AccessRestrictionType.PUSH);

		AccessPolicy namedPushPolicy = new AccessPolicy(getString("gb.namedPushPolicy"),
				getString("gb.namedPushPolicyDescription"),
				"lock_go_16x16.png",
				AuthorizationControl.NAMED,
				AccessRestrictionType.PUSH);

		AccessPolicy clonePolicy = new AccessPolicy(getString("gb.clonePolicy"),
				getString("gb.clonePolicyDescription"),
				"lock_pull_16x16.png",
				AuthorizationControl.NAMED,
				AccessRestrictionType.CLONE);

		AccessPolicy viewPolicy = new AccessPolicy(getString("gb.viewPolicy"),
				getString("gb.viewPolicyDescription"),
				"shield_16x16.png",
				AuthorizationControl.NAMED,
				AccessRestrictionType.VIEW);

		List<AccessPolicy> policies = new ArrayList<AccessPolicy>();
		if (app().settings().getBoolean(Keys.git.allowAnonymousPushes, false)) {
			policies.add(anonymousPolicy);
		}
		policies.add(authenticatedPushPolicy);
		policies.add(namedPushPolicy);
		policies.add(clonePolicy);
		policies.add(viewPolicy);

		AccessRestrictionType defaultRestriction = repository.accessRestriction;
		if (defaultRestriction == null) {
			defaultRestriction = AccessRestrictionType.fromName(app().settings().getString(Keys.git.defaultAccessRestriction,
					AccessRestrictionType.PUSH.name()));
		}

		AuthorizationControl defaultControl = repository.authorizationControl;
		if (defaultControl == null) {
			defaultControl = AuthorizationControl.fromName(app().settings().getString(Keys.git.defaultAuthorizationControl,
					AuthorizationControl.NAMED.name()));
		}

		AccessPolicy defaultPolicy = namedPushPolicy;
		for (AccessPolicy policy : policies) {
			if (policy.type == defaultRestriction && policy.control == defaultControl) {
				defaultPolicy = policy;
			}
		}

		policiesGroup = new RadioGroup<>("policiesGroup", new Model<AccessPolicy>(defaultPolicy));
		ListView<AccessPolicy> policiesList = new ListView<AccessPolicy>("policies", policies) {

			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(ListItem<AccessPolicy> item) {
				AccessPolicy p = item.getModelObject();
				item.add(new Radio<AccessPolicy>("radio", item.getModel()));
				item.add(WicketUtils.newImage("image",  p.image));
				item.add(new Label("name", p.name));
				item.add(new Label("description", p.description));
			}
		};
		policiesGroup.add(policiesList);
		if (callback != null) {
			policiesGroup.add(callback);
			policiesGroup.setOutputMarkupId(true);
		}
		add(policiesGroup);

		allowForks = Model.of(app().settings().getBoolean(Keys.web.allowForking, true));
		if (allowForks.getObject()) {
			Fragment fragment = new Fragment("allowForks", "allowForksFragment", this);
			fragment.add(new BooleanOption("allowForks",
				getString("gb.allowForks"),
				getString("gb.allowForksDescription"),
				allowForks));
			add(fragment);
		} else {
			add(new Label("allowForks").setVisible(false));
		}

		setOutputMarkupId(true);
	}

	public void updateModel(RepositoryModel repository) {
		AccessPolicy policy = policiesGroup.getModelObject();
		repository.authorizationControl = policy.control;
		repository.accessRestriction = policy.type;
		repository.allowForks = allowForks.getObject();
	}

	@Override
	protected boolean getStatelessHint() {
		return false;
	}

	public static class AccessPolicy implements Serializable {

		private static final long serialVersionUID = 1L;

		final String name;
		final String description;
		final String image;
		final AuthorizationControl control;
		final AccessRestrictionType type;

		AccessPolicy(String name, String description, String img, AuthorizationControl control, AccessRestrictionType type) {
			this.name = name;
			this.description = description;
			this.image = img;
			this.control = control;
			this.type = type;
		}

		@Override
		public String toString() {
			return name;
		}
	}
}
