package com.atlassian.stash.internal.ao;

import com.atlassian.activeobjects.spi.DatabaseType;
import com.atlassian.stash.internal.jdbc.DataSourceConfiguration;
import com.atlassian.tenancy.api.Tenant;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.sql.DataSource;

import static org.junit.Assert.*;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class ApplicationDataSourceProviderTest {

    @Mock
    private DataSourceConfiguration configuration;
    @Mock
    private DataSource dataSource;
    @Mock
    private Tenant tenant;
    @InjectMocks
    private ApplicationDataSourceProvider provider;

    @Test
    public void testGetDatasource() {
        assertEquals(dataSource, provider.getDataSource(tenant));
    }

    @Test
    public void testGetDatabaseTypeHsql() {
        when(configuration.getUrl()).thenReturn("jdbc:hsqldb:mem:accounts",
                "jdbc:hsqldb:hsql://localhost/enrollments;get_column_name=false");
        assertEquals(DatabaseType.HSQL, provider.getDatabaseType(tenant));
        assertEquals(DatabaseType.HSQL, provider.getDatabaseType(tenant));

        verify(configuration, times(2)).getUrl(); //Verify it's not cached
    }

    @Test
    public void testGetDatabaseTypeMysql() {
        when(configuration.getUrl()).thenReturn("jdbc:mysql://localhost:3306/sakila?profileSQL=true");
        assertEquals(DatabaseType.MYSQL, provider.getDatabaseType(tenant));
    }

    @Test
    public void testGetDatabaseTypePostgresql() {
        when(configuration.getUrl()).thenReturn("jdbc:postgresql:database");
        assertEquals(DatabaseType.POSTGRESQL, provider.getDatabaseType(tenant));
    }

    @Test
    public void testGetDatabaseTypeOracle() {
        when(configuration.getUrl()).thenReturn("jdbc:oracle:thin:@//myhost:1521/orc");
        assertEquals(DatabaseType.ORACLE, provider.getDatabaseType(tenant));
    }

    @Test
    public void testGetDatabaseTypeMsSQL() {
        when(configuration.getUrl()).thenReturn("jdbc:sqlserver://localhost;user=MyUserName;password=*****",
                "jdbc:jtds:sqlserver://MYPC:1433/Blog;instance=SQLEXPRESS;user=sa;password=s3cr3t");
        assertEquals(DatabaseType.MS_SQL, provider.getDatabaseType(tenant));
        assertEquals(DatabaseType.MS_SQL, provider.getDatabaseType(tenant));

        verify(configuration, times(2)).getUrl();
    }

    @Test
    public void testGetDatabaseTypeOther() {
        when(configuration.getUrl()).thenReturn(null, "", "jdbc:jtds:sybase://127.0.0.1:5000/SAMPLE");
        assertEquals(DatabaseType.UNKNOWN, provider.getDatabaseType(tenant));
        assertEquals(DatabaseType.UNKNOWN, provider.getDatabaseType(tenant));
        assertEquals(DatabaseType.UNKNOWN, provider.getDatabaseType(tenant));

        verify(configuration, times(3)).getUrl();
    }
}