/*******************************************************************************
 * Copyright (c) 2020 Aston University.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License, v. 2.0 are satisfied: GNU General Public License, version 3.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-3.0
 *
 * Contributors:
 *    Antonio Garcia-Dominguez - initial API and implementation
 *******************************************************************************/
package org.eclipse.hawk.ui.localfolder;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.hawk.core.IVcsManager;
import org.eclipse.hawk.localfolder.LocalFile;
import org.eclipse.hawk.osgiserver.HModel;
import org.eclipse.hawk.ui2.dialog.HVCSDialog;
import org.eclipse.hawk.ui2.vcs.IVcsConfigurationBlock;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class LocalFileConfigurationBlock implements IVcsConfigurationBlock {

	private HVCSDialog dialog;
	private Text txtVCSLocation;
	private Button btnVCSBrowse;

	@Override
	public boolean isApplicableTo(IVcsManager manager) {
		return manager instanceof LocalFile;
	}

	@Override
	public void createBlock(Composite container, HVCSDialog dialog) {
		this.dialog = dialog;
		final IVcsManager managerToEdit = dialog.getManagerToEdit();

		final GridLayout containerLayout = new GridLayout();
		containerLayout.numColumns = 3;
		container.setLayout(containerLayout);

		// Location + browse
		final Label lblLocation = new Label(container, SWT.NONE);
		lblLocation.setText("Location:");
		txtVCSLocation = new Text(container, SWT.BORDER);
		final GridData txtVCSLocationLayoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		txtVCSLocationLayoutData.widthHint = 300;
		txtVCSLocation.setLayoutData(txtVCSLocationLayoutData);
		if (managerToEdit != null) {
			txtVCSLocation.setText(managerToEdit.getLocation());
			txtVCSLocation.setEnabled(false);
		} else {
			txtVCSLocation.setText(dialog.getSelectedVCSManager().getDefaultLocation());
		}
		txtVCSLocation.addModifyListener(e -> updateDialog());

		btnVCSBrowse = new Button(container, SWT.PUSH);
		GridData gridDataB = new GridData();
		btnVCSBrowse.setLayoutData(gridDataB);
		btnVCSBrowse.setText("Browse...");
		btnVCSBrowse.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				FileDialog fd = new FileDialog(container.getShell(), SWT.OPEN);
				fd.setFilterPath(ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().toString());
				fd.setText("Select a file");
				String result = fd.open();
				if (result != null) {
					txtVCSLocation.setText(result);
				}
			}
		});
		btnVCSBrowse.setEnabled(false);

		updateDialog();
	}

	@Override
	public void okPressed(HModel hawkModel, boolean isFrozen) {
		final String vcsType = dialog.getSelectedVCSManager().getClass().getName();
		final String location = txtVCSLocation.getText();

		final IVcsManager managerToEdit = dialog.getManagerToEdit();
		if (managerToEdit == null) {
			hawkModel.addVCS(location, vcsType, "", "", isFrozen);
		} else {
			managerToEdit.setFrozen(isFrozen);
		}
	}

	private void updateDialog() {
		if (dialog.getManagerToEdit() == null) {
			final IVcsManager vcsManager = dialog.getSelectedVCSManager();
			btnVCSBrowse.setEnabled(vcsManager != null && vcsManager.isPathLocationAccepted());
		}

		if (!isLocationValid()) {
			dialog.setErrorMessage("The location is not valid");
		} else if (dialog.getSelectedVCSManager() == null) {
			dialog.setErrorMessage("No VCS manager type has been selected");
		} else {
			dialog.setErrorMessage(null);
		}
	}

	private boolean isLocationValidPath() {
		File file = new File(txtVCSLocation.getText());
		if (file.exists() && file.isFile() && file.canRead())
			return true;
		return false;
	}

	private boolean isLocationValid() {
		IVcsManager vcsManager = dialog.getSelectedVCSManager();
		return vcsManager.isPathLocationAccepted() && isLocationValidPath()
				|| vcsManager.isURLLocationAccepted() && isLocationValidURI();
	}

	private boolean isLocationValidURI() {
		try {
			URI uri = new URI(txtVCSLocation.getText());
			return uri.getScheme() != null && uri.getPath() != null;
		} catch (URISyntaxException e) {
			return false;
		}
	}

}
