package com.atlassian.stash.internal.backup.liquibase;

import com.atlassian.bitbucket.annotation.Dao;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.util.PageRequestImpl;
import com.atlassian.stash.internal.project.*;
import com.atlassian.stash.internal.repository.HibernateRepositoryDao;
import com.atlassian.stash.internal.repository.InternalRepository;
import com.atlassian.stash.internal.repository.RepositoryDao;
import com.atlassian.stash.internal.user.*;
import org.hamcrest.Matchers;
import org.junit.Before;

/**
 * Simple migration test with basic data (a project, a repository, an user and global/project permissions),
 * which backups and restores the data to the same database.
 */
public class SimpleMigrationTest extends AbstractLiquibaseMigrationTest {

    @Dao(HibernateProjectDao.class)
    private ProjectDao projectDao;
    @Dao(HibernateRepositoryDao.class)
    private RepositoryDao repositoryDao;
    @Dao(HibernateGlobalPermissionDao.class)
    private GlobalPermissionDao globalPermissionDao;
    @Dao(HibernateProjectPermissionDao.class)
    private ProjectPermissionDao projectPermissionDao;
    @Dao(HibernateStashUserDao.class)
    private StashUserDao stashUserDao;

    private InternalPersonalProject personalProject;
    private InternalProject project;
    private InternalRepository repository;
    private InternalNormalUser user;
    private InternalApplicationUser userCalledNull;
    private InternalApplicationUser userWithQuotes;
    private InternalGlobalPermission[] globalPermissions;
    private InternalProjectPermission[] projectPermissions;

    @Before
    public void disableBackupRemoval() {
        removeBackupAfterTest = false;
    }

    @Override
    protected void populateData() {
        user = stashUserDao.create(new InternalNormalUser.Builder().name("user").build()).accept(InternalNormalUser.TO_NORMAL_USER);
        userWithQuotes = stashUserDao.create(new InternalNormalUser.Builder().name("'username in quotes'").build());
        userCalledNull = stashUserDao.create(new InternalNormalUser.Builder().name("null").build());
        project = projectDao.create(new InternalNormalProject.Builder()
                .description("Sample project").key("testprj").name("TestProject").build());
        personalProject = (InternalPersonalProject) projectDao.create(new InternalPersonalProject.Builder()
                .owner(user)
                .build());
        repository = repositoryDao.create(new InternalRepository.Builder()
                .hierarchyId("wtfbbq").name("repo").project(project).scmId("git").build());
        globalPermissions = new InternalGlobalPermission[] {
                globalPermissionDao.create(new InternalGlobalPermission.Builder()
                        .permission(Permission.LICENSED_USER).user(user).build())
        };
        projectPermissions = new InternalProjectPermission[] {
                projectPermissionDao.create(new InternalProjectPermission.Builder()
                        .permission(Permission.PROJECT_READ).user(user).project(project).build()),
                projectPermissionDao.create(new InternalProjectPermission.Builder()
                        .permission(Permission.PROJECT_ADMIN).user(user).project(personalProject).build())
        };
    }

    @Override
    protected void compareRestoredData() {
        assertEquals(user, stashUserDao.findByName("user"));
        assertEquals(userWithQuotes, stashUserDao.findByName("'username in quotes'"));
        assertEquals(userCalledNull, stashUserDao.findByName("null"));
        assertEquals(personalProject, projectDao.getByKey(null, InternalPersonalProject.createPersonalProjectKey(user)));
        assertEquals(project, projectDao.getByKey(null, "testprj"));
        assertEquals(repository, repositoryDao.getBySlug(null, "testprj", "repo"));
        assertThat(globalPermissionDao.findAll(new PageRequestImpl(0, 10)).getValues(), Matchers.<InternalGlobalPermission>hasItems(globalPermissions));
        assertThat(projectPermissionDao.findAll(new PageRequestImpl(0, 10)).getValues(), Matchers.<InternalProjectPermission>hasItems(projectPermissions));
    }
}
