/*
 * 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.userstorage.internal.util.StringUtil;
import org.eclipse.userstorage.oauth.OAuthParameters;

/**
 * A variant of {@link OAuthParameters} that allows overriding the OAuth
 * parameters via creative overriding of the {@link #getProperty(String, String)}
 * method.  Note that {@link #getClientId()} and {@link #getClientSecret()}
 * only return the overridden value, if any, and never the decrypted value.
 */
public class EditableOAuthParameters extends OAuthParameters {
	private URI service;
	private String clientId;
	private String clientSecret;
	private String[] scopes;
	private URI expectedCallback;
	
	@Override
	protected String getServiceName() {
		return "uss";
	}
	
	@Override
	protected String getDefaultClientSecret() {
		return "efdba0d50960c6803b633ae6a5bd0a6fbc814294c51457ebaabf6d99";
	}
	
	@Override
	protected String getDefaultClientKey() {
		return "91bb4c33f3b5552b798be6c84205e6c92bf5af212d8efae55bdaee";
	}
	
	@Override
	protected String getDefaultClientId() {
		return "83aa479cdf5248d18f9628859df5d08e";
	}

	public void setService(URI service) {
		this.service = service;
	}

	/** @return the overridden client ID, or {@code null} if not changed */
	public String getClientId() {
		return clientId;
	}

	public void setClientId(String clientId) {
		this.clientId = clientId;
	}

	/** @return the overridden client secret, or {@code null} if not changed */
	public String getClientSecret() {
		return clientSecret;
	}

	public void setClientSecret(String clientSecret) {
		this.clientSecret = clientSecret;
	}

	public void setScopes(String[] scopes) {
		this.scopes = scopes;
	}

	public void setExpectedCallback(URI expectedCallback) {
		this.expectedCallback = expectedCallback;
	}

	/** Look up property values in our local fields. */
	@Override
	protected String getProperty(String propName, String defaultValue) {
		if(propName.equals(getServiceName() + PROP_CLIENT_ID) && clientId != null) {
			return clientId;
		} else if(propName.equals(getServiceName() + PROP_CLIENT_SECRET) && clientSecret != null) {
				return clientSecret;
		} else if(propName.equals(getServiceName() + PROP_EXPECTED_CALLBACK) && expectedCallback != null) {
			return expectedCallback.toASCIIString();
		} else if(propName.equals(getServiceName() + PROP_SCOPES) && scopes != null) {
			return StringUtil.join(",", scopes);
		} else if(propName.equals(getServiceName() + PROP_SERVICE) && service != null) {
			return service.toASCIIString();
		}
		return super.getProperty(propName, defaultValue);
	}
	
	
}
