/*
 *  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.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;

import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.model.GitStatusContainer;
import org.apache.openaz.xacml.admin.model.GitStatusContainer.GitEntry;
import org.apache.openaz.xacml.admin.model.GitStatusContainer.StatusItem;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Item;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
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.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class GitPushWindow extends Window {

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

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Button buttonPush;
	@AutoGenerated
	private Table tableChanges;
	@AutoGenerated
	private TextArea textAreaComments;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(GitPushWindow.class);
	private final GitPushWindow self = this;
	private final GitStatusContainer container;
	private final Git git;
	private final File target;
	private boolean isSaved = false;
	/**
	 * 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.
	 * @param git 
	 * @param status 
	 */
	public GitPushWindow(Git git, File target, Status status) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Save data
		//
		this.git = git;
		this.target = target;
		this.container = new GitStatusContainer(status);
		//
		// Set our shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Initialize GUI
		//
		this.initializeText();
		this.initializeTable(status);
		this.initializeButtons();
		//
		//  Focus
		//
		this.textAreaComments.focus();
	}
	
	protected void initializeText() {
		this.textAreaComments.setImmediate(true);
		this.textAreaComments.addTextChangeListener(new TextChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void textChange(TextChangeEvent event) {
				if (event.getText().isEmpty()) {
					self.buttonPush.setEnabled(false);
				} else {
					if (self.container.getConflictCount() == 0) {
						self.buttonPush.setEnabled(true);
					} else {
						self.buttonPush.setEnabled(false);
					}
				}
			}			
		});
	}

	protected void initializeTable(Status status) {
		//
		// Setup the table
		//
		this.tableChanges.setContainerDataSource(this.container);
		this.tableChanges.setPageLength(this.container.size());
		this.tableChanges.setImmediate(true);
		//
		// Generate column
		//
		this.tableChanges.addGeneratedColumn("Entry", new ColumnGenerator() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object generateCell(Table source, Object itemId, Object columnId) {
				Item item = self.container.getItem(itemId);
				assert item != null;
				if (item instanceof StatusItem) {
					return self.generateGitEntryComponent(((StatusItem) item).getGitEntry());
				}
				assert item instanceof StatusItem;
				return null;
			}
		});
	}
	
	protected Object generateGitEntryComponent(final GitEntry entry) {
		//
		// If its conflicting, take care of it
		//
		if (entry.isConflicting()) {
			return this.generateConflictingEntry(entry);
		}
		if (entry.isUntracked()) {
			return this.generateUntrackedEntry(entry);
		}
		/*
		if (entry.isChanged() ||
			entry.isModified() ||
			entry.isUncommitted()) {
			return this.generateUncommittedEntry(entry);
		}
		*/
		return null;
	}
	
	protected Object generateConflictingEntry(final GitEntry entry) {
		Button resolve = new Button("Resolve");
		resolve.setImmediate(true);
		resolve.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
		
			}
		});
		return resolve;
	}
	
	protected Object generateUntrackedEntry(final GitEntry entry) {
		Button add = new Button("Add");
		add.setImmediate(true);
		add.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					DirCache cache = self.git.add().addFilepattern(entry.getName()).call();
					DirCacheEntry cacheEntry = cache.getEntry(entry.getName());
					assert cacheEntry != null;
					if (cacheEntry == null) {
						return;
					}
					if (cacheEntry.isMerged()) {
						self.refreshStatus();
					}
				} catch (GitAPIException e) {
					String error = "Failed to add: " + e.getLocalizedMessage();
					logger.error(error);
					AdminNotification.error(error);
				}
			}
		});
		return add;
	}
	
	protected Object generateUncommittedEntry(final GitEntry entry) {
		Button commit = new Button("Commit");
		commit.setImmediate(true);
		commit.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
			}
		});
		return commit;
	}
	
	protected void initializeButtons() {
		this.buttonPush.setEnabled(false);
		this.buttonPush.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit
					//
					self.textAreaComments.commit();
					//
					// Mark as saved
					//
					self.isSaved = true;
					//
					// Close the window
					//
					self.close();
				} catch(SourceException | InvalidValueException idontcare) { //NOPMD
					//
					// Vaadin will highlight the failed requirement or validation
					//
				}
			}			
		});
	}
	
	protected void	refreshStatus() {
		try {
			//
			// Grab our working repository
			//
			Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
			final Git git = Git.open(repoPath.toFile());
			//
			// Get our status
			//
			final String base;
			Status status;
			if (target == null) {
				base = ".";
			} else {
				Path relativePath = repoPath.relativize(Paths.get(target.getPath()));
				base = relativePath.toString();
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Status on base: " + base);
			}
			status = git.status().addPath(base).call();
			//
			// Pass it to our container
			//
			this.container.refreshStatus(status);
			this.tableChanges.refreshRowCache();
		} catch (NoWorkTreeException | IOException | GitAPIException e) {
			String error = "Failed to refresh status: " + e.getLocalizedMessage();
			logger.error(error);
		}
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public String getComment() {
		return this.textAreaComments.getValue();
	}

	@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");
		
		// textAreaComments
		textAreaComments = new TextArea();
		textAreaComments.setCaption("Add Comments");
		textAreaComments.setImmediate(false);
		textAreaComments
				.setDescription("Enter comments that reflect the changes you have made to the repository domains and/or policy files.");
		textAreaComments.setWidth("400px");
		textAreaComments.setHeight("-1px");
		textAreaComments.setInvalidAllowed(false);
		textAreaComments.setRequired(true);
		textAreaComments
				.setInputPrompt("Eg. Add new rule for employees in marketing department.");
		mainLayout.addComponent(textAreaComments);
		
		// tableChanges
		tableChanges = new Table();
		tableChanges.setCaption("Changes To Be Pushed");
		tableChanges.setImmediate(false);
		tableChanges.setWidth("100.0%");
		tableChanges.setHeight("-1px");
		mainLayout.addComponent(tableChanges);
		mainLayout.setExpandRatio(tableChanges, 1.0f);
		
		// buttonPush
		buttonPush = new Button();
		buttonPush.setCaption("Push Changes");
		buttonPush.setImmediate(true);
		buttonPush.setWidth("-1px");
		buttonPush.setHeight("-1px");
		mainLayout.addComponent(buttonPush);
		mainLayout.setComponentAlignment(buttonPush, new Alignment(48));
		
		return mainLayout;
	}

}
