package com.atlassian.bitbucket.mesh;

import com.atlassian.bitbucket.mesh.layout.StorageLayout;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.io.ClassPathResource;

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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class H2DatabaseValidatorTest {

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Mock
    private StorageLayout storageLayout;

    @Before
    public void setUp() {
        when(storageLayout.getHomeDir()).thenReturn(folder.getRoot().toPath());
    }

    @Test
    public void testCompatibleH2DatabaseFile() throws IOException {
        FileUtils.copyFile(new ClassPathResource("h2/mesh-2.2.x.mv.db").getFile(),
                new File(folder.getRoot(), "mesh.mv.db"));
        H2DatabaseValidator validator = new H2DatabaseValidator(storageLayout);

        validator.validate();
    }

    @Test
    public void testIncompatibleH2DatabaseFile_1_X() throws IOException {
        FileUtils.copyFile(new ClassPathResource("h2/mesh-1.x.mv.db").getFile(),
                new File(folder.getRoot(), "mesh.mv.db"));
        H2DatabaseValidator validator = new H2DatabaseValidator(storageLayout);

        UnsupportedH2StoreException exception = assertThrows(UnsupportedH2StoreException.class, validator::validate);
        assertEquals("The storage format for the internal database that you are using has changed and requires " +
                "manual migration.", exception.getMessage());
        assertEquals("Please perform the manual migration of the database. See https://confluence.atlassian.com/bitbucketserver088/migrate-h2-database-1216583295.html.",
                exception.getAction());
    }

    @Test
    public void testIncompatibleH2DatabaseFile_2_1() throws IOException {
        FileUtils.copyFile(new ClassPathResource("h2/mesh-2.1.x.mv.db").getFile(),
                new File(folder.getRoot(), "mesh.mv.db"));
        H2DatabaseValidator validator = new H2DatabaseValidator(storageLayout);

        UnsupportedH2StoreException exception = assertThrows(UnsupportedH2StoreException.class, validator::validate);
        assertEquals("The storage format for the internal database that you are using has changed and requires " +
                "manual migration.", exception.getMessage());
        assertEquals("Please perform the manual migration of the database. See https://confluence.atlassian.com/bitbucketserver088/migrate-h2-database-1216583295.html.",
                exception.getAction());
    }

    @Test
    public void testIncompatibleH2DatabaseFile() throws IOException {
        FileUtils.copyFile(new ClassPathResource("h2/mesh-1.x.mv.db").getFile(),
                new File(folder.getRoot(), "mesh.mv.db"));

        H2DatabaseValidator validator = new H2DatabaseValidator(storageLayout);

        UnsupportedH2StoreException exception = assertThrows(UnsupportedH2StoreException.class, validator::validate);
        assertEquals("The storage format for the internal database that you are using has changed and requires " +
                "manual migration.", exception.getMessage());
        assertEquals("Please perform the manual migration of the database. See https://confluence.atlassian.com/bitbucketserver088/migrate-h2-database-1216583295.html.",
                exception.getAction());
    }
}