package be.iminds.ilabt.jfed.lowlevel.authority;

import be.iminds.ilabt.jfed.JFedWebApiClientModule;
import be.iminds.ilabt.jfed.experimenter_gui.util.ConnectivityDetector;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Testbed;
import be.iminds.ilabt.jfed.lowlevel.TestbedInfoSource;
import be.iminds.ilabt.jfed.preferences.CorePreferenceKey;
import be.iminds.ilabt.jfed.preferences.JFedCorePreferences;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.util.GeniUrn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.mock;

public class BasicTestbedInfoSourceTest {
    private static final Logger LOG = LoggerFactory.getLogger(BasicTestbedInfoSourceTest.class);

    private final static String ONLY_TOP_EXISTS_TOP_URN_STRING = "urn:publicid:IDN+wall2.ilabt.iminds.be+authority+cm";
    private final static String ONLY_TOP_EXISTS_SUB_URN_STRING = "urn:publicid:IDN+wall2.ilabt.iminds.be:fakesubauth+authority+cm";
    private final static String ONLY_TOP_EXISTS_SUB_SUB_SUB_URN_STRING = "urn:publicid:IDN+wall2.ilabt.iminds.be:fakesubauth:fake2:fake3+authority+cm";
    private final static String ONLY_SUB_EXISTS_TOP_URN_STRING = "urn:publicid:IDN+ple+authority+cm";
    private final static String ONLY_SUB_EXISTS_SUB_URN_STRING = "urn:publicid:IDN+ple:ibbtple+authority+cm";
    private final static String ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN_STRING = "urn:publicid:IDN+ple:ibbtple:fakesub:fakesub2:fakesub3+authority+cm";
    private final static String EXOGENI_URN_STRING = "urn:publicid:IDN+exogeni.net+authority+am";
    private final static String EXOGENI_BBN_URN_STRING = "urn:publicid:IDN+exogeni.net:bbnvmsite+authority+am";
    private final static String EXOGENI_BBN_FAKESUB_URN_STRING = "urn:publicid:IDN+exogeni.net:bbnvmsite:fakesub+authority+am";

    private final static GeniUrn ONLY_TOP_EXISTS_TOP_URN = GeniUrn.parse(ONLY_TOP_EXISTS_TOP_URN_STRING);
    private final static GeniUrn ONLY_TOP_EXISTS_SUB_URN = GeniUrn.parse(ONLY_TOP_EXISTS_SUB_URN_STRING);
    private final static GeniUrn ONLY_TOP_EXISTS_SUB_SUB_SUB_URN = GeniUrn.parse(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN_STRING);
    private final static GeniUrn ONLY_SUB_EXISTS_TOP_URN = GeniUrn.parse(ONLY_SUB_EXISTS_TOP_URN_STRING);
    private final static GeniUrn ONLY_SUB_EXISTS_SUB_URN = GeniUrn.parse(ONLY_SUB_EXISTS_SUB_URN_STRING);
    private final static GeniUrn ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN = GeniUrn.parse(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN_STRING);
    private final static GeniUrn EXOGENI_URN = GeniUrn.parse(EXOGENI_URN_STRING);
    private final static GeniUrn EXOGENI_BBN_URN = GeniUrn.parse(EXOGENI_BBN_URN_STRING);
    private final static GeniUrn EXOGENI_BBN_FAKESUB_URN = GeniUrn.parse(EXOGENI_BBN_FAKESUB_URN_STRING);

    private JFedPreferences jFedPreferences;
    private TestbedInfoSource testbedInfoSource;
    private AuthorityFinder authorityFinder;
    private be.iminds.ilabt.jfed.log.Logger logger;

    private boolean exoPrefersTopLevel = true;

    @BeforeClass
    public void setup() throws MalformedURLException {
        jFedPreferences = new JFedCorePreferences(); //note: corePreferences does NOT autosave
        jFedPreferences.setString(CorePreferenceKey.PREF_TESTBEDS_JSON_SOURCE, "BUILTIN");
        jFedPreferences.setString(CorePreferenceKey.PREF_GUICONFIG_SOURCE, "BUILTIN");
        URL webApiUrl = new URL(JFedWebApiClientModule.DEFAULT_URL_STRING);
        testbedInfoSource = new JFedTestbedInfoSource(jFedPreferences, new ConnectivityDetector(null), webApiUrl, logger).get();
        authorityFinder = new AuthorityFinder(testbedInfoSource, jFedPreferences);
        logger = new be.iminds.ilabt.jfed.log.Logger();

        //check if load ok
        assertThat(testbedInfoSource.getTestbeds(), hasSize(greaterThan(10)));
        assertThat(testbedInfoSource.getServers(), hasSize(greaterThan(10)));

        for (Testbed testbed : testbedInfoSource.getTestbeds()) {
            LOG.debug("Known testbed: "+testbed.getId()+"   "+testbed.getDefaultComponentManagerUrn());
        }

        //check if URNs required for test are as expected
        List<GeniUrn> requiredUrns = Arrays.asList(EXOGENI_URN, EXOGENI_BBN_URN, ONLY_TOP_EXISTS_TOP_URN, ONLY_SUB_EXISTS_SUB_URN);
        for (GeniUrn requiredUrn : requiredUrns) {
            assertThat("testbedInfoSource is missing " + requiredUrn, testbedInfoSource.getByUrnExact(requiredUrn), is(notNullValue()));
        }
        List<GeniUrn> forbiddenUrns = Arrays.asList(EXOGENI_BBN_FAKESUB_URN, ONLY_TOP_EXISTS_SUB_URN,
                ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, ONLY_SUB_EXISTS_TOP_URN, ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN);
        for (GeniUrn forbiddenUrn : forbiddenUrns) {
            assertThat("testbedInfoSource has urn it should not have " + forbiddenUrn, testbedInfoSource.getByUrnExact(forbiddenUrn), is(nullValue()));
        }

        exoPrefersTopLevel = authorityFinder.findByUrn(EXOGENI_URN, AuthorityFinder.Purpose.RECOVER).hasFlag(Server.Flag.preferToplevelOverSubauthority);
    }


    @DataProvider(name = "ignoreUrnTypeAndName")
    public static Object[][] ignoreUrnTypeAndName() {

        Object[][] res = new Object[2][];
        res[0] = new Object[] { true };
        res[1] = new Object[] { false };
        return res;
    }

    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect1(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_ONLY_EXACT_SUBAUTHORITY;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_EXACT_SUBAUTHORITY;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
    }
    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect2(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_TOPLEVEL;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_EXACT_SUBAUTHORITY;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
    }
    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect3(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_OTHER_SUBAUTHORITY;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_EXACT_SUBAUTHORITY;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
    }
    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect4(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_ONLY_EXACT_SUBAUTHORITY;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_TOPLEVEL;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
    }
    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect5(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_TOPLEVEL;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_TOPLEVEL;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName), is(nullValue()));
    }
    @Test(dataProvider = "ignoreUrnTypeAndName")
    public void testGetByUrnDirect6(boolean ignoreUrnTypeAndName) {
        TestbedInfoSource.SubAuthMatchAllowed allowed = TestbedInfoSource.SubAuthMatchAllowed.ALLOW_OTHER_SUBAUTHORITY;
        TestbedInfoSource.SubAuthMatchPreference preferred = TestbedInfoSource.SubAuthMatchPreference.PREFER_TOPLEVEL;

        assertThat(testbedInfoSource.getByUrn(EXOGENI_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(EXOGENI_BBN_FAKESUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(testbedInfoSource.getByUrn(ONLY_SUB_EXISTS_TOP_URN, allowed, preferred, ignoreUrnTypeAndName).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
    }


    @DataProvider(name = "forceExoSmConfig")
    public static Object[][] forceExoSmConfig() {

        Object[][] res = new Object[3][];
        res[0] = new Object[] { "YES" };
        res[1] = new Object[] { "NO" };
        res[2] = new Object[] { "AUTO" };
        return res;
    }


    @Test(dataProvider = "forceExoSmConfig")
    public void testGetByUrnPurpose1(String exoSmConfig) {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.CREATE_SLIVER;
        jFedPreferences.setString(CorePreferenceKey.PREF_TESTBEDSPECIFIC_EXOGENI_FORCE_EXOSM, exoSmConfig);
        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));

        if (exoSmConfig.equalsIgnoreCase("yes") || (exoSmConfig.equalsIgnoreCase("auto") && exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        }
        if (exoSmConfig.equalsIgnoreCase("no") || (exoSmConfig.equalsIgnoreCase("auto") && !exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        }

        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
//        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose).getUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test(dataProvider = "forceExoSmConfig")
    public void testGetByUrnPurpose2(String exoSmConfig) {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.RECOVER;

        jFedPreferences.setString(CorePreferenceKey.PREF_TESTBEDSPECIFIC_EXOGENI_FORCE_EXOSM, exoSmConfig);
        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));

        if (exoSmConfig.equalsIgnoreCase("yes") || (exoSmConfig.equalsIgnoreCase("auto") && exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        }
        if (exoSmConfig.equalsIgnoreCase("no") || (exoSmConfig.equalsIgnoreCase("auto") && !exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        }

        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test
    public void testGetByUrnPurpose3() {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.RECOVER_BOTH_FIRST;

        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test
    public void testGetByUrnPurpose4() {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.RECOVER_BOTH_SECOND;

        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test
    public void testGetByUrnPurpose5() {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.REQUEST_RSPEC;

        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test(dataProvider = "forceExoSmConfig")
    public void testGetByUrnPurpose6(String exoSmConfig) {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.STATUS;
        jFedPreferences.setString(CorePreferenceKey.PREF_TESTBEDSPECIFIC_EXOGENI_FORCE_EXOSM, exoSmConfig);

        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));

        if (exoSmConfig.equalsIgnoreCase("yes") || (exoSmConfig.equalsIgnoreCase("auto") && exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        }
        if (exoSmConfig.equalsIgnoreCase("no") || (exoSmConfig.equalsIgnoreCase("auto") && !exoPrefersTopLevel)) {
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
            assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        }

        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }
    @Test(dataProvider = "forceExoSmConfig")
    public void testGetByUrnPurpose7(String exoSmConfig) {
        AuthorityFinder.Purpose purpose = AuthorityFinder.Purpose.STITCHING;
        jFedPreferences.setString(CorePreferenceKey.PREF_TESTBEDSPECIFIC_EXOGENI_FORCE_EXOSM, exoSmConfig);

        assertThat(authorityFinder.findByUrn(EXOGENI_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_URN, purpose).getDefaultComponentManagerUrn(), equalTo(EXOGENI_BBN_URN_STRING));
        assertThat(authorityFinder.findByUrn(EXOGENI_BBN_FAKESUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_TOP_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_TOP_EXISTS_TOP_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_TOP_EXISTS_SUB_SUB_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_URN, purpose).getDefaultComponentManagerUrn(), equalTo(ONLY_SUB_EXISTS_SUB_URN_STRING));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_SUB_SUB_SUB_SUB_URN, purpose), is(nullValue()));
        assertThat(authorityFinder.findByUrn(ONLY_SUB_EXISTS_TOP_URN, purpose), is(nullValue()));
    }

//    @Test
//    public void testSortBySubAuthDifference() throws Exception {
//        List<Server> start = new ArrayList<Server>();
//        start.add(new Server("urn:publicid:IDN+example.net+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+example.com:one+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+ex.com:xxxxxxxxxxxxxxxxxxxxxxx:2+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+example.com:aaaaa:bbbbb:three+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+example.com:c:d:e:four+authority+cm"));
//
//        List<Server> actual = AuthorityListModel.sortBySubAuthDifference(start, new GeniUrn("urn:publicid:IDN+example.com:u:two+authority+cm"));
//        System.out.println("actual=" + actual);
//
//        assertThat(actual, is(start));
//        assertThat(actual, hasSize(5));
//        assertThat(actual.get(0).getDefaultComponentManagerUrn(), equalTo(new GeniUrn("urn:publicid:IDN+ex.com:xxxxxxxxxxxxxxxxxxxxxxx:2+authority+cm")));
//        assertThat(actual.get(1).getDefaultComponentManagerUrn(), isOneOf(new GeniUrn("urn:publicid:IDN+example.com:one+authority+cm"), new GeniUrn("urn:publicid:IDN+example.com:aaaaa:bbbbb:three+authority+cm")));
//        assertThat(actual.get(2).getDefaultComponentManagerUrn(), isOneOf(new GeniUrn("urn:publicid:IDN+example.com:one+authority+cm"), new GeniUrn("urn:publicid:IDN+example.com:aaaaa:bbbbb:three+authority+cm")));
//        assertThat(actual.get(1).getDefaultComponentManagerUrn(), not(equalTo(actual.get(2).getDefaultComponentManagerUrn())));
//        assertThat(actual.get(3).getDefaultComponentManagerUrn(), isOneOf(new GeniUrn("urn:publicid:IDN+example.net+authority+cm"), new GeniUrn("urn:publicid:IDN+example.com:c:d:e:four+authority+cm")));
//        assertThat(actual.get(4).getDefaultComponentManagerUrn(), isOneOf(new GeniUrn("urn:publicid:IDN+example.net+authority+cm"), new GeniUrn("urn:publicid:IDN+example.com:c:d:e:four+authority+cm")));
//        assertThat(actual.get(3).getDefaultComponentManagerUrn(), not(equalTo(actual.get(4).getDefaultComponentManagerUrn())));
//    }
//
//    @Test
//    public void testSortBySubAuthNumber() throws Exception {
//        List<Server> start = new ArrayList<Server>();
//        start.add(new Server("urn:publicid:IDN+example.net+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+example.com:one+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+example.com:aaaaa:bbbbb:three+authority+cm"));
//        start.add(new Server("urn:publicid:IDN+ex.com:c:d:e:four+authority+cm"));
//
//        List<Server> expected = new ArrayList<Server>();
//        expected.add(new Server("urn:publicid:IDN+example.net+authority+cm"));
//        expected.add(new Server("urn:publicid:IDN+example.com:one+authority+cm"));
//        expected.add(new Server("urn:publicid:IDN+example.com:aaaaa:bbbbb:three+authority+cm"));
//        expected.add(new Server("urn:publicid:IDN+ex.com:c:d:e:four+authority+cm"));
//
//        List<Server> actual = AuthorityListModel.sortBySubAuthNumber(start);
//        System.out.println("actual="+actual);
//
//        assertThat(actual, is(start));
//        assertThat(actual, equalTo(expected));
//    }
}
