/*
 * Copyright (c) 2016 Manumitting Technologies Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Manumitting Technologies Inc - initial API and implementation
 */
package org.eclipse.userstorage.sdk.browser;

import java.net.URI;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.userstorage.internal.util.StringUtil;

/**
 * Updates the provided {@link EditableOAuthParameters} in-place.
 */
public class OAuthClientDetailsDialog extends TrayDialog {
	private EditableOAuthParameters parameters;
	
	private Text authorizationURIText;
	private Text clientIdText;
	private Text clientSecretText;
	private Text scopesText;
	private Text expectedCallbackURIText;

	/**
	 * Create the dialog.
	 * 
	 * @param parentShell
	 */
	public OAuthClientDetailsDialog(Shell parentShell, EditableOAuthParameters parameters) {
		super(parentShell);
		this.parameters = parameters;
	}

	@Override
	public void create() {
		super.create();
		// validation and restore must be done after dialog contents are created
		validate();
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(new GridLayout(2, false));

		Label lblAuthorizationURI = new Label(container, SWT.NONE);
		lblAuthorizationURI.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblAuthorizationURI.setText("Authorization URI:");

		authorizationURIText = new Text(container, SWT.BORDER);
		authorizationURIText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		authorizationURIText.setText(parameters.getService().toString());

		Label lblClientId = new Label(container, SWT.NONE);
		lblClientId.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblClientId.setText("Client ID:");

		clientIdText = new Text(container, SWT.BORDER);
		clientIdText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		if(parameters.getClientId() != null) {
			clientIdText.setText(parameters.getClientId());
		}
		clientIdText.setMessage("not shown: using compile-time value");

		Label lblClientSecret = new Label(container, SWT.NONE);
		lblClientSecret.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblClientSecret.setText("Client Secret:");

		clientSecretText = new Text(container, SWT.BORDER);
		clientSecretText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
		if (parameters.getClientSecret() != null) {
			clientSecretText.setText(parameters.getClientSecret());
		}
		clientSecretText.setMessage("not shown: using compile-time value");

		Label lblScopes = new Label(container, SWT.NONE);
		lblScopes.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblScopes.setToolTipText("Space or comma-separated");
		lblScopes.setText("Scopes:");

		scopesText = new Text(container, SWT.BORDER);
		scopesText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		scopesText.setText(StringUtil.join(", ", parameters.getScopes()));

		Label lblCallback = new Label(container, SWT.NONE);
		lblCallback.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblCallback.setText("Callback URI:");

		expectedCallbackURIText = new Text(container, SWT.BORDER);
		expectedCallbackURIText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		expectedCallbackURIText.setText(parameters.getExpectedCallback().toString());

		ModifyListener modifyListener = new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				validate();
			}
		};
		authorizationURIText.addModifyListener(modifyListener);
		clientIdText.addModifyListener(modifyListener);
		clientSecretText.addModifyListener(modifyListener);
		scopesText.addModifyListener(modifyListener);
		expectedCallbackURIText.addModifyListener(modifyListener);

		return container;
	}

	private void validate() {
		getButton(IDialogConstants.OK_ID).setEnabled(isValid());
	}

	private boolean isValid() {
		try {
			// URL is less forgiving than URI
			parameters.setService(URI.create(authorizationURIText.getText()));
			parameters.setExpectedCallback(URI.create(expectedCallbackURIText.getText()));
		} catch (IllegalArgumentException e) {
			return false;
		}

		String newClientId = clientIdText.getText().trim();
		String newClientSecret = clientSecretText.getText().trim();
		if (newClientId.matches("\\w+") ^ newClientSecret.matches("\\w+")) {
			// must specify both or neither
			return false;
		}
		parameters.setClientId(newClientId);
		parameters.setClientSecret(newClientSecret);

		String scopesString = scopesText.getText().trim();
		if (!scopesString.matches("(\\w+,?\\s*)+")) {
			return false;
		}
		parameters.setScopes(scopesText.getText().trim().split("[,\\s]\\s*"));
		return true;
	}

	/**
	 * Create contents of the button bar.
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(450, 300);
	}
}
