package com.atlassian.stash.internal.liquibase;

import com.atlassian.bitbucket.annotation.Dao;
import com.atlassian.bitbucket.annotation.DataSet;
import com.atlassian.stash.internal.AbstractDaoTest;
import com.atlassian.stash.internal.DataSets;
import com.atlassian.stash.internal.user.*;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import javax.sql.DataSource;

/**
 * Tests that {@link AddServiceUserColumnsChange} correctly updates the {@code sta_service_user} table.
 * <p>
 * This test can only run if STASHDEV-9310-2 to STASHDEV-9310-7 are disabled in 3.9/upgrade.xml
 */
@DataSet(value = DataSets.PREFIX + "liquibase/add_service_user_columns" + DataSets.SUFFIX)
@Ignore("This test can't be run at present as it expects to be run after a certain set of Liquibase changesets " +
        "have been executed but is actually run after all have been executed and the schema, especially the " +
        "user tables, has advanced too far.")
public class AddServiceUserColumnsChangeTest extends AbstractDaoTest {

    @Autowired
    private DataSource dataSource;
    @Dao(HibernateStashUserDao.class)
    private StashUserDao userDao;

    @Test
    public void testExecute() throws Exception {
        JdbcConnection connection = new JdbcConnection(dataSource.getConnection());
        Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);

        AddServiceUserColumnsChange change = new AddServiceUserColumnsChange();
        change.execute(database);
        assertEquals("11 sta_service_user rows were updated", change.getConfirmationMessage());

        // 16 id FreudBot - no category should be set
        assertUser(userDao.getById(16), InternalServiceUser.DEFAULT_LABEL);

        for (int id : new int[] {1, 2, 15, 17, 18, 19, 20, 21, 22, 23}) {
            assertUser(userDao.getById(id), "access-key");
        }
    }

    private void assertUser(InternalApplicationUser user, String category) {
        assertNotNull(user);

        String userId = "user " + user.getId();
        assertTrue(userId + " is not a ServiceUser", user instanceof InternalServiceUser);
        InternalServiceUser serviceUser = (InternalServiceUser) user;

        assertNotNull(userId + ".name", serviceUser.getName());
        assertNotNull(userId + ".slug", serviceUser.getSlug());
        assertEquals(userId + ".category doesn't match", category, serviceUser.getLabel());
        assertTrue(userId + ".active was false", serviceUser.isActive());
    }
}
