/*******************************************************************************
 * Copyright (c) 2020 Christian Pontesegger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/

package org.eclipse.skills.service;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;

import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
import org.eclipse.skills.service.storage.IDataStorage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class UserStorageTest {

	// @formatter:off
	private static final byte[] DEFAULT_USER = ("<?xml version=\"1.0\" encoding=\"ASCII\"?>\n"
			+ "<skills:User xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:skills=\"http://eclipse.org/skills/1.0.0\" name=\"John Doe\">\n"
			+ "  <usertasks>\n"
			+ "    <task href=\"platform:/plugin/org.eclipse.skills/resources/UnitTest.skills#UnitTest_Quest_First_task\"/>\n"
			+ "  </usertasks>\n"
			+ "  <experience name=\"Experience\" experience=\"30\">\n"
			+ "    <progression xsi:type=\"skills:FactorProgression\"/>\n"
			+ "  </experience>\n"
			+ "</skills:User>\n").getBytes();
	// @formatter:on

	private static byte[] getDamagedProfile() {
		final byte[] damagedProfile = Arrays.copyOf(DEFAULT_USER, DEFAULT_USER.length);
		damagedProfile[0] = 'x';
		return damagedProfile;
	}

	private UserStorage fUserStorage;
	private IDataStorage fStorageMock;

	@BeforeEach
	public void setup() {
		fStorageMock = mock(IDataStorage.class);
		fUserStorage = new UserStorage(fStorageMock);
	}

	@Test
	@DisplayName("resetProgress() re-initializes the user")
	public void resetProgressReInitializesUser() throws IOException {
		final IUser defaultUser = loadDefaultUser();

		final String oldName = defaultUser.getName();
		final String oldAvatar = defaultUser.getImageLocation();

		fUserStorage.resetProgress();

		assertEquals(oldName, fUserStorage.getUser().getName());
		assertEquals(oldAvatar, fUserStorage.getUser().getImageLocation());
		assertEquals(0, fUserStorage.getUser().getExperience().getExperience());
		assertTrue(fUserStorage.getUser().getBadges().isEmpty());
	}

	@Test
	@DisplayName("getUser() creates a default user when storage is empty")
	public void getUserCreatesDefaultUserOnEmptyStorage() {
		final IUser user = fUserStorage.getUser();

		assertNotNull(user.getName());
	}

	@Test
	@DisplayName("getUser() loads data from storage")
	public void getUserLoadsDataFromStorage() {
		final IUser user = loadDefaultUser();

		assertEquals("John Doe", user.getName());
	}

	@Test
	@DisplayName("getUser() contains resolved usertask -> task references")
	void resolveTaskReferences() {
		final IUser user = loadDefaultUser();

		assertFalse(user.getUsertasks().isEmpty());
		for (final IUserTask usertask : user.getUsertasks())
			assertFalse(usertask.getTask().eIsProxy());
	}

	@Test
	@DisplayName("On a damaged profile the old one gets backup'ed")
	public void backupOnDamagedProfile() throws IOException {

		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
		when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());

		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1")).thenReturn(false);

		fUserStorage.getUser();

		verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1", getDamagedProfile());
	}

	@Test
	@DisplayName("On a damaged profile backups do not get overwritten")
	public void backupOnDamagedProfileDoesNotOverwrite() throws IOException {

		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1")).thenReturn(true);
		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "2")).thenReturn(false);
		when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());

		fUserStorage.getUser();

		verify(fStorageMock, times(0)).storeResource(eq(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1"), any());
		verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "2", getDamagedProfile());
	}

	@Test
	@DisplayName("On a damaged profile a new user gets created")
	public void newUserOnDamagedProfile() throws IOException {

		when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
		when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());

		assertNotNull(fUserStorage.getUser());
	}

	@Test
	@DisplayName("storeUser() saves the user instance")
	public void storeUser() throws IOException {
		final IUser user = loadDefaultUser();

		fUserStorage.storeUser(user);

		verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE, DEFAULT_USER);
	}

	private IUser loadDefaultUser() {
		try {
			when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
			when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(DEFAULT_USER);

			return fUserStorage.getUser();
		} catch (final IOException e) {
			throw new UncheckedIOException(e);
		}
	}
}
