package brooklyn.location.basic;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

import brooklyn.config.BrooklynProperties;
import brooklyn.entity.basic.Entities;
import brooklyn.location.Location;
import brooklyn.location.LocationDefinition;
import brooklyn.management.internal.LocalManagementContext;

public class LocationRegistryTest {
    
    private static final Logger log = LoggerFactory.getLogger(LocationRegistryTest.class);
    
    private LocalManagementContext mgmt;
    private LocationDefinition locdef;

    @AfterMethod(alwaysRun = true)
    public void tearDown(){
        if (mgmt != null) Entities.destroyAll(mgmt);
    }

    @Test
    public void testNamedLocationsPropertyDefinedLocations() {
        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
        mgmt = new LocalManagementContext(properties);
        log.info("foo properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
        Assert.assertNotNull(locdef, "Expected 'foo' location; but had "+mgmt.getLocationRegistry().getDefinedLocations());
        Assert.assertEquals(locdef.getConfig().get("privateKeyFile"), "~/.ssh/foo.id_rsa");
    }
    
    @Test(dependsOnMethods="testNamedLocationsPropertyDefinedLocations")
    public void testResolvesByNamedAndId() {
        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
        mgmt = new LocalManagementContext(properties);

        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
        log.info("testResovlesBy has defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
        
        Location l = mgmt.getLocationRegistry().resolve("named:foo");
        Assert.assertNotNull(l);
        Assert.assertEquals(l.getLocationProperty("privateKeyFile"), "~/.ssh/foo.id_rsa");
        
        l = mgmt.getLocationRegistry().resolve("foo");
        Assert.assertNotNull(l);
        Assert.assertEquals(l.getLocationProperty("privateKeyFile"), "~/.ssh/foo.id_rsa");
        
        l = mgmt.getLocationRegistry().resolve("id:"+locdef.getId());
        Assert.assertNotNull(l);
        Assert.assertEquals(l.getLocationProperty("privateKeyFile"), "~/.ssh/foo.id_rsa");
        
        l = mgmt.getLocationRegistry().resolve(locdef.getId());
        Assert.assertNotNull(l);
        Assert.assertEquals(l.getLocationProperty("privateKeyFile"), "~/.ssh/foo.id_rsa");
    }

    @Test
    public void testSetupForTesting() {
        mgmt = new LocalManagementContext();
        BasicLocationRegistry.setupLocationRegistryForTesting(mgmt);
        Assert.assertNotNull(mgmt.getLocationRegistry().getDefinedLocationByName("localhost"));
    }

    @Test
    public void testCircularReference() {
        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
        properties.put("brooklyn.location.named.bar", "named:bar");
        mgmt = new LocalManagementContext(properties);
        log.info("bar properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
        boolean resolved = false;
        try {
            mgmt.getLocationRegistry().resolve("bar");
            resolved = true;
        } catch (IllegalStateException e) {
            //expected
            log.info("bar properties correctly caught circular reference: "+e);
        }
        if (resolved)
            // probably won't happen, if test fails will loop endlessly above
            Assert.fail("Circular reference resolved location");
    }
    
}

@@ -2986,32 +2986,1195 @@
 d_rsa%22);%0A    %7D%0A%0A
+    @Test%0A    public void testLocationGetsDisplayName() %7B%0A        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();%0A        properties.put(%22brooklyn.location.named.foo%22, %22byon:(hosts=%5C%22root@192.168.1.%7B1,2,3,4%7D%5C%22)%22);%0A        properties.put(%22brooklyn.location.named.foo.displayName%22, %22My Foo%22);%0A        mgmt = new LocalManagementContext(properties);%0A        Location l = mgmt.getLocationRegistry().resolve(%22foo%22);%0A        Assert.assertEquals(l.getDisplayName(), %22My Foo%22);%0A    %7D%0A    %0A    @Test%0A    public void testLocationGetsDefaultDisplayName() %7B%0A        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();%0A        properties.put(%22brooklyn.location.named.foo%22, %22byon:(hosts=%5C%22root@192.168.1.%7B1,2,3,4%7D%5C%22)%22);%0A        mgmt = new LocalManagementContext(properties);%0A        Location l = mgmt.getLocationRegistry().resolve(%22foo%22);%0A        Assert.assertEquals(l.getDisplayName(), null);%0A        // TODO currently it gives null; it would be nice to use 'foo', %0A        // or at least to have access to the spec (and use it e.g. in places such as DynamicFabric)%0A//        Assert.assertEquals(l.getDisplayName(), %22foo%22);%0A    %7D%0A    %0A
     @Test%0A    pu

test picking up display names for locations, and comments