package com.atlassian.bitbucket.mesh.repository;

import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Collection;
import java.util.Collections;

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

@RunWith(MockitoJUnitRunner.class)
public class DefaultRepositoryAttributeManagerTest {

    private static final String REPOSITORY = "p/0000/h/abc123abc123abc123ab/r/0001112223";

    @Mock
    private RepositoryAttributeDao dao;
    @InjectMocks
    private DefaultRepositoryAttributeManager repositoryAttributeManager;

    @Test
    public void testDeleteAttributes() {
        repositoryAttributeManager.delete("repositoryId");

        verify(dao).delete("repositoryId");
    }

    @Test
    public void testGetContentHash() {
        String hash = StringUtils.repeat('A', 64);
        when(dao.getContentHash(REPOSITORY)).thenReturn(hash);
        assertEquals(hash, repositoryAttributeManager.getContentHash(REPOSITORY));
        verify(dao).getContentHash(REPOSITORY);
    }

    @Test
    public void testGetMetadataHash() {
        String hash = StringUtils.repeat('B', 64);
        when(dao.getMetadataHash(REPOSITORY)).thenReturn(hash);
        assertEquals(hash, repositoryAttributeManager.getMetadataHash(REPOSITORY));
        verify(dao).getMetadataHash(REPOSITORY);
    }

    @Test
    public void testIsReadOnlyFalse() {
        when(dao.isReadOnly(REPOSITORY)).thenReturn(false);
        assertFalse(repositoryAttributeManager.isReadOnly(REPOSITORY));
        verify(dao).isReadOnly(REPOSITORY);
    }

    @Test
    public void testIsReadOnlyTrue() {
        when(dao.isReadOnly(REPOSITORY)).thenReturn(true);
        assertTrue(repositoryAttributeManager.isReadOnly(REPOSITORY));
        verify(dao).isReadOnly(REPOSITORY);
    }

    @Test
    public void testReplaceReadOnly() {
        repositoryAttributeManager.replaceReadOnly(Collections.singleton(REPOSITORY));
        verify(dao).replaceReadOnly(ArgumentMatchers.argThat(Matchers.contains(REPOSITORY)::matches));
    }

    @Test
    public void testReplaceReadOnlyEmpty() {
        repositoryAttributeManager.replaceReadOnly(Collections.emptySet());
        verify(dao).replaceReadOnly(ArgumentMatchers.argThat(Collection::isEmpty));
    }

    @Test
    public void testSetContentHash() {
        String hash = StringUtils.repeat('C', 64);
        repositoryAttributeManager.setContentHash(REPOSITORY, hash);
        verify(dao).setContentHash(eq(REPOSITORY), eq(hash));
    }

    @Test
    public void testMetadataHash() {
        String hash = StringUtils.repeat('D', 64);
        repositoryAttributeManager.setMetadataHash(REPOSITORY, hash);
        verify(dao).setMetadataHash(eq(REPOSITORY), eq(hash));
    }

    @Test
    public void testSetReadOnlyFalse() {
        repositoryAttributeManager.setReadOnly(REPOSITORY, true);
        verify(dao).setReadOnly(REPOSITORY, true);
    }

    @Test
    public void testSetReadOnlyTrue() {
        repositoryAttributeManager.setReadOnly(REPOSITORY, true);
        verify(dao).setReadOnly(REPOSITORY, true);
    }
}