/*
 *  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.windows;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

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.model.GitRepositoryContainer;
import org.apache.openaz.xacml.admin.model.GitRepositoryContainer.FileItem;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import org.apache.openaz.xacml.std.pap.StdPDPPolicy;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class SelectWorkspacePoliciesWindow extends Window {
	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private Button buttonSave;

	@AutoGenerated
	private TreeTable treeWorkspace;

	private static Log	logger	= LogFactory.getLog(SelectWorkspacePoliciesWindow.class);

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

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final SelectWorkspacePoliciesWindow self = this;
	private GitRepositoryContainer treeContainer;
	private boolean isSaved = false;
	private StdPDPPolicy selectedPolicy = null;
	
	
	
	/**
	 * 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 SelectWorkspacePoliciesWindow() {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		this.buttonSave.setClickShortcut(KeyCode.ENTER);
		//
		//
		//
		this.initializeTree();
		this.initializeButton();
		//
		//
		//
		this.treeWorkspace.focus();
	}
	
	protected void initializeTree() {
		//
		// This is where the user's Git repository is located
		//
		final Path gitPath = ((XacmlAdminUI)UI.getCurrent()).getUserGitPath();
		//
		// Create our Git file system container
		//
		this.treeContainer = new GitRepositoryContainer(gitPath, gitPath.toFile());
		//
		// Create our own filter to filter out File extensions and
		// also the Git directory.
		//
		this.treeContainer.setFilter(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				//
				// We don't want any of the hidden files
				//
				if (name.startsWith(".git") || name.equals(".DS_Store")) {
					return false;
				}
				//
				// We definitely want xml files
				//
				if (name.endsWith(".xml")) {
					return true;
				}
				//
				// We should test if its a directory, we want those
				// included.
				//
				Path path = Paths.get(dir.getAbsolutePath(), name);
				if (Files.isDirectory(path)) {
					return true;
				}
				logger.warn("Filtering out: " + path.toString());
				return false;
			}
			
		});
		//
		// Set TreeTables datasource as our git container
		//
		this.treeWorkspace.setContainerDataSource(this.treeContainer);
		//
		// Setup other properties etc.
		//
		this.treeWorkspace.setItemIconPropertyId("Icon");
		this.treeWorkspace.setVisibleColumns(new Object[]{"Name", "Version", "Size", "Last Modified", "Status"});
		this.treeWorkspace.setSizeFull();
		this.treeWorkspace.setSelectable(true);
		this.treeWorkspace.setEditable(false);
		//
		// Expand the first couple of directories
		//
		for (Object id : this.treeWorkspace.getItemIds()) {
			this.treeWorkspace.setCollapsed(id, false);
			for (Object child : this.treeWorkspace.getChildren(id)) {
				this.treeWorkspace.setCollapsed(child, false);
			}
		}
		//
		// Respond to table selections
		//
		this.treeWorkspace.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				if (self.treeWorkspace.getValue() != null) {
					self.buttonSave.setEnabled(true);
				} else {
					self.buttonSave.setEnabled(false);
				}
			}
		});
		//
		// Double-click events
		//
		this.treeWorkspace.addItemClickListener(new ItemClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void itemClick(ItemClickEvent event) {
				if (event.isDoubleClick()) {
					//
					// Save and close
					//
					self.doSave();
				}
			}
		});
	}
	
	protected void initializeButton() {
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				assert treeWorkspace.getValue() != null;
				//
				// Save everything
				//
				self.doSave();
			}
		});
	}
	
	protected void doSave() {
		//
		// Get the current selection
		//
		FileItem selectedItem = (FileItem) this.treeWorkspace.getItem(this.treeWorkspace.getValue());
		//
		//
		//
		assert selectedItem != null;
		if (selectedItem == null) {
			return;
		}
		
		// create the id of the target file
		
		// Our standard for file naming is:
		//		<domain>.<filename>.<version>.xml
		
		// since the file name usually has a ".xml", we need to strip that before adding the other parts
		String name = selectedItem.getName();
		String id = name;
		if (id.endsWith(".xml")) {
			id = id.substring(0, id.length() - 4);
		}
		
		// add on the version string

		String version = selectedItem.getVersion();
		id += "." + version;
		
		// put the .xml on the end
		id += ".xml";
		
		// tack on the domain in front.  Do this one level at a time until we reach one of the roots
	

		File parentFile = selectedItem.getFile();
		while ((parentFile = (File) this.treeWorkspace.getParent(parentFile)) != null) {
			if (this.treeContainer.isRoot(parentFile)) {
				break;
			}
			id = parentFile.getName() + "." + id;
		}
		
		// Default policy to be Root policy;  user can change to deferred later
		URI selectedURI = selectedItem.getFile().toURI();
		try {
			//
			// Create the policy
			//
			this.selectedPolicy = new StdPDPPolicy(id, true, name, selectedURI);
			//
			// Mark ourselves as saved
			//
			this.isSaved = true;
		} catch (IOException e) {
			logger.error("Unable to create policy '" + id + "': " + e.getMessage());
			AdminNotification.warn("Unable to create policy '" + id + "': " + e.getMessage());
		}

		//
		// Close the window
		//
		this.close();
	}

	public boolean isSaved() {
		return this.isSaved;
	}
	
	public StdPDPPolicy getSelectedPolicy() {
		return this.selectedPolicy;
	}

	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(true);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// treeWorkspace
		treeWorkspace = new TreeTable();
		treeWorkspace.setCaption("Select Policy(s) for PDP Group");
		treeWorkspace.setImmediate(true);
		treeWorkspace.setWidth("100.0%");
		treeWorkspace.setHeight("-1px");
		mainLayout.addComponent(treeWorkspace);
		
		// buttonSave
		buttonSave = new Button();
		buttonSave.setCaption("Save");
		buttonSave.setImmediate(false);
		buttonSave.setWidth("-1px");
		buttonSave.setHeight("-1px");
		mainLayout.addComponent(buttonSave);
		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
		
		return mainLayout;
	}


	
	
	
	
}
