package com.atlassian.stash.internal.plugin.web.fragments;

import com.atlassian.plugin.hostcontainer.HostContainer;
import com.atlassian.plugin.module.ModuleFactory;
import com.atlassian.plugin.webresource.WebResourceIntegration;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class WebFragmentLocationModuleDescriptorTest {
    @Mock
    private ModuleFactory moduleFactory;
    @Mock
    private HostContainer hostContainer;
    @Mock
    private ClientWebInterfaceManager clientWebInterfaceManager;
    @Mock
    private ClientPageDataHandler clientPageDataHandler;
    @Mock
    private WebResourceIntegration webResourceIntegration;
    @InjectMocks
    private WebFragmentLocationModuleDescriptor descriptor;

    @Test
    public void testGetNoWebSectionDependencies() {
        HashSet<String> derivedLocations = new HashSet<String>();
        Set<String> webSectionDependencies = descriptor.getWebSectionDependencies(Lists.<String>newArrayList(), derivedLocations);
        assertTrue(webSectionDependencies.isEmpty());
        assertTrue(derivedLocations.isEmpty());
    }

    @Test
    public void testGetWebSectionDependenciesWhenThereAreNone() {
        HashSet<String> derivedLocations = new HashSet<String>();
        Set<String> webSectionDependencies = descriptor.getWebSectionDependencies(Lists.newArrayList("loc1", "loc2"), derivedLocations);
        assertTrue(webSectionDependencies.isEmpty());
        assertTrue(derivedLocations.isEmpty());
    }

    @Test
    public void testGetWebSectionDependencies() {
        List<ClientWebSectionModuleDescriptor> loc1Children = Lists.newArrayList(mockDescriptor("loc1-child1", "moduleA"), mockDescriptor("loc1-child2", "moduleB"));
        when(clientWebInterfaceManager.getSections("loc1")).thenReturn(loc1Children);
        List<ClientWebSectionModuleDescriptor> loc2Children = Lists.newArrayList(mockDescriptor("loc2-child1", "moduleC"));
        when(clientWebInterfaceManager.getSections("loc2")).thenReturn(loc2Children);

        HashSet<String> derivedLocations = new HashSet<String>();
        Set<String> webSectionDependencies = descriptor.getWebSectionDependencies(Lists.newArrayList("loc1", "loc2"), derivedLocations);

        assertEquals(Sets.newHashSet("loc1-child1:moduleA", "loc1-child2:moduleB", "loc2-child1:moduleC"), webSectionDependencies);
        assertEquals(Sets.newHashSet("location@loc1-child1/moduleA", "location@loc1-child2/moduleB", "location@loc2-child1/moduleC", "moduleA", "moduleB", "moduleC"), derivedLocations);
    }

    @Test
    public void testGetWebSectionDependenciesWithDuplicates() {
        List<ClientWebSectionModuleDescriptor> loc1Children = Lists.newArrayList(mockDescriptor("loc1-child1", "moduleA"), mockDescriptor("loc1-child2", "moduleB"));
        when(clientWebInterfaceManager.getSections("loc1")).thenReturn(loc1Children);
        List<ClientWebSectionModuleDescriptor> loc2Children = Lists.newArrayList(mockDescriptor("loc1-child1", "moduleA"), mockDescriptor("loc2-child1", "moduleC"));
        when(clientWebInterfaceManager.getSections("loc2")).thenReturn(loc2Children);

        HashSet<String> derivedLocations = new HashSet<String>();
        Set<String> webSectionDependencies = descriptor.getWebSectionDependencies(Lists.newArrayList("loc1", "loc2"), derivedLocations);

        assertEquals(Sets.newHashSet("loc1-child1:moduleA", "loc1-child2:moduleB", "loc2-child1:moduleC"), webSectionDependencies);
        assertEquals(Sets.newHashSet("location@loc1-child1/moduleA", "location@loc1-child2/moduleB", "location@loc2-child1/moduleC", "moduleA", "moduleB", "moduleC"), derivedLocations);
    }

    private ClientWebSectionModuleDescriptor mockDescriptor(String pluginKey, String moduleKey) {
        ClientWebSectionModuleDescriptor descriptor = mock(ClientWebSectionModuleDescriptor.class);
        when(descriptor.getPluginKey()).thenReturn(pluginKey);
        when(descriptor.getKey()).thenReturn(moduleKey);
        when(descriptor.getCompleteKey()).thenReturn(pluginKey + ":" + moduleKey);
        when(descriptor.getLocation()).thenReturn("location@" + pluginKey);
        return descriptor;
    }
}
