/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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 org.apache.openaz.xacml.admin.view.components;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
import org.apache.openaz.xacml.admin.jpa.PIPResolver;
import org.apache.openaz.xacml.admin.view.windows.PIPResolverEditorWindow;
import org.apache.openaz.xacml.std.pip.engines.csv.ConfigurableCSVResolver;
import org.apache.openaz.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver;
import org.apache.openaz.xacml.std.pip.engines.ldap.ConfigurableLDAPResolver;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.util.filter.Compare;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

public class PIPResolverComponent extends CustomComponent {
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Table tableResolvers;
	
	private final Action ADD_RESOLVER = new Action("Add Resolver");
	private final Action EDIT_RESOLVER = new Action("Edit Resolver");
	private final Action CLONE_RESOLVER = new Action("Clone Resolver");
	private final Action REMOVE_RESOLVER = new Action("Remove Resolver");

	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(PIPResolverComponent.class);
	
	private final PIPResolverComponent self = this;
	private final PIPConfiguration config;
	
	private final JPAContainer<PIPResolver> resolverContainer = new JPAContainer<PIPResolver>(PIPResolver.class);

	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public PIPResolverComponent(PIPConfiguration configuration) {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Save
		//
		this.config = configuration;
		this.resolverContainer.setEntityProvider(new CachingMutableLocalEntityProvider<PIPResolver>(PIPResolver.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
		this.resolverContainer.addContainerFilter(new Compare.Equal("pipconfiguration", this.config));
		//
		// Initialize GUI
		//
		this.initializeTable();
	}
	
	protected void initializeTable() {
		//
		// Setup the container datasource
		//
		this.tableResolvers.setContainerDataSource(this.resolverContainer);
		//
		// Set GUI properties
		//
		this.tableResolvers.setImmediate(true);
		this.tableResolvers.setVisibleColumns(new Object[] {"name", "description", "issuer"});
		this.tableResolvers.setColumnHeaders(new String[] {"Name", "Description", "Issuer"});
		this.tableResolvers.setPageLength(this.config.getPipresolvers().size() + 1);
		this.tableResolvers.setSizeFull();
		this.tableResolvers.setSelectable(true);
		//
		// Add the actions
		//
		this.tableResolvers.addActionHandler(new Handler() {
			private static final long serialVersionUID = 1L;

			@Override
			public Action[] getActions(Object target, Object sender) {
				if (target == null) {
					return new Action[] {ADD_RESOLVER};
				}
				return new Action[] {EDIT_RESOLVER, CLONE_RESOLVER, REMOVE_RESOLVER};
			}

			@Override
			public void handleAction(Action action, Object sender, Object target) {
				if (action == ADD_RESOLVER) {
					PIPResolverComponent.addResolver(self.config, null);
					return;
				}
				if (action == EDIT_RESOLVER) {
					PIPResolverComponent.editResolver(self.resolverContainer.getItem(target));
					return;
				}
				if (action == CLONE_RESOLVER) {
					PIPResolverComponent.addResolver(self.config, self.resolverContainer.getItem(target).getEntity());
					return;
				}
				if (action == REMOVE_RESOLVER) {
					self.removeResolver(self.config, self.resolverContainer.getItem(target).getEntity());
					return;
				}
			}
		});
		//
		// Respond to events
		//
		this.tableResolvers.addItemClickListener(new ItemClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {
				if (event.isDoubleClick()) {
					Object id = event.getItemId();
					if (id == null) {
						return;
					}
					PIPResolverComponent.editResolver(self.resolverContainer.getItem(id));
				}
			}
		});
	}
	
	protected void removeResolver(PIPConfiguration config, PIPResolver resolver) {
		config.removePipresolver(resolver);
		this.tableResolvers.removeItem(resolver.getId());
	}

	public static void	addResolver(PIPConfiguration config, PIPResolver pipResolver) {
		//
		// Create the entity
		//
		PIPResolver resolver = null;
		if (pipResolver != null) {
			resolver = new PIPResolver(pipResolver);
		} else {
			resolver = new PIPResolver();
		}
		resolver.setCreatedBy(((XacmlAdminUI)UI.getCurrent()).getUserid());
		resolver.setModifiedBy(((XacmlAdminUI)UI.getCurrent()).getUserid());
		resolver.setPipconfiguration(config);
		//
		// Set its default class
		//
		if (config.getPiptype().isSQL()) {
			resolver.setClassname(ConfigurableJDBCResolver.class.getCanonicalName());
		} else if (config.getPiptype().isLDAP()) {
			resolver.setClassname(ConfigurableLDAPResolver.class.getCanonicalName());
		} else if (config.getPiptype().isCSV()) {
			resolver.setClassname(ConfigurableCSVResolver.class.getCanonicalName());
		} else if (config.getPiptype().isHyperCSV()) {
			resolver.setClassname(ConfigurableJDBCResolver.class.getCanonicalName());
		}
		//
		// Bring up the editor window
		//
		PIPResolverComponent.editResolver(((XacmlAdminUI)UI.getCurrent()).getPIPResolvers().createEntityItem(resolver));
		
	}
	
	public static void	editResolver(final EntityItem<PIPResolver> entity) {
		
		final PIPResolverEditorWindow window = new PIPResolverEditorWindow(entity);
		window.setModal(true);
		window.center();
		if (entity.isPersistent()) {
			window.setCaption("Edit Resolver");
		} else {
			window.setCaption("Create Resolver");
		}
		window.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				//
				// Did the user click "save"?
				//
				if (window.isSaved() == false) {
					return;
				}
				//
				// Adding a new entity?
				//
				if (entity.isPersistent() == false) {
					//
					// Yes - let's official add it
					//
					((XacmlAdminUI)UI.getCurrent()).getPIPResolvers().addEntity(entity.getEntity());
					((XacmlAdminUI)UI.getCurrent()).refreshPIPConfiguration();
				}
			}
		});
		UI.getCurrent().addWindow(window);
	}

	public static void publishConfiguration(EntityItem<PIPConfiguration> config) {
		Properties properties = config.getEntity().generateProperties(Integer.toString(config.getEntity().getId()));
		
		try {
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			properties.store(os, "");
			if (logger.isDebugEnabled()) {
				logger.debug(os.toString());
			}
		} catch (IOException e) { //NOPMD
			// TODO - Handle, Log or NOPMD
			// TODO - Will vaadin display error?
		}
	}
		
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(false);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// tableResolvers
		tableResolvers = new Table();
		tableResolvers.setCaption("Resolvers");
		tableResolvers.setImmediate(false);
		tableResolvers.setWidth("-1px");
		tableResolvers.setHeight("-1px");
		mainLayout.addComponent(tableResolvers);
		
		return mainLayout;
	}
}
