package org.eclipse.userstorage.oauth;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;

import org.eclipse.userstorage.internal.oauth.OAuthCredentialsPersistence;
import org.eclipse.userstorage.internal.oauth.OAuthCredentialsPersistence.LinkedAccount;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class OAuthCredentialPersistenceTest {

	@Rule
	public TemporaryFolder tempDirectory = new TemporaryFolder();

	@Test
	public void testRoundTrip() throws IOException {
		File location = tempDirectory.newFile();
		OAuthCredentialsPersistence writer = new OAuthCredentialsPersistence(location);
		writer.putAccountToken("clientId", "http://authURI/?foo=bar", "token", "email");

		assertTrue("persisted location exists", location.exists());
		assertTrue("persisted file is non-empty", location.length() > 0);

		OAuthCredentialsPersistence reader = new OAuthCredentialsPersistence(location);
		assertEquals("should be a single account", 1, reader.getLinkedAccounts().length);
		assertEquals("token", reader.getAccountToken("clientId", "http://authURI/?foo=bar"));

		assertNull("should be null on same client but diff authURI", reader.getAccountToken("clientId", "different"));
		assertNull("should be null on same authURI but diff clientId",
				reader.getAccountToken("differentId", "http://authURI/?foo=bar"));
		assertNull("should be null on non-extant entry", reader.getAccountToken("differentId", "diffAuthURI"));
	}

	@Test
	public void testRemoval() throws IOException {
		File location = tempDirectory.newFile();
		OAuthCredentialsPersistence persister = new OAuthCredentialsPersistence(location);
		persister.putAccountToken("clientId", "authURI", "token", "email");
		assertEquals("should be a single account", 1, persister.getLinkedAccounts().length);

		persister.removeAccountToken("clientId", "authURI");
		assertEquals("should have 0 accounts", 0, persister.getLinkedAccounts().length);
		assertNull(persister.getAccountToken("clientId", "authURI"));
	}

	@Test
	public void testHasEmail() throws IOException {
		File location = tempDirectory.newFile();
		OAuthCredentialsPersistence persister = new OAuthCredentialsPersistence(location);
		persister.putAccountToken("clientId", "http://authURI/?foo=bar", "token", "email");

		LinkedAccount[] linkedAccounts = persister.getLinkedAccounts();
		assertEquals(1, linkedAccounts.length);
		assertEquals("clientId", linkedAccounts[0].clientId);
		assertEquals("http://authURI/?foo=bar", linkedAccounts[0].authURI);
		assertEquals("email", linkedAccounts[0].email);
	}

	@Test
	public void testNoEmail() throws IOException {
		File location = tempDirectory.newFile();
		OAuthCredentialsPersistence persister = new OAuthCredentialsPersistence(location);
		persister.putAccountToken("clientId", "http://authURI/?foo=bar", "token", null);

		LinkedAccount[] linkedAccounts = persister.getLinkedAccounts();
		assertEquals(1, linkedAccounts.length);
		assertEquals("clientId", linkedAccounts[0].clientId);
		assertEquals("http://authURI/?foo=bar", linkedAccounts[0].authURI);
		assertNull("should be null email", linkedAccounts[0].email);
	}

}
