package brooklyn.entity.dns;

import java.net.InetAddress;

import brooklyn.entity.Entity;
import brooklyn.location.Location;
import brooklyn.location.MachineLocation;

/**
 * Encapsulates geo-IP information for a given host.
 */
public class HostGeoInfo {
    public final String address;
    public final String displayName;
    public final double latitude;
    public final double longitude;

    
    public static HostGeoInfo fromLocation(Location l) {
        InetAddress address = findIpAddress(l);
        Double latitude = (Double) l.findLocationProperty("latitude");
        Double longitude = (Double) l.findLocationProperty("longitude");

        if (address == null || latitude == null || longitude == null)
            return null;
        
        return new HostGeoInfo(address.toString(), l.getName(), latitude, longitude);
    }
    
    public static HostGeoInfo fromEntity(Entity e) {
        for (Location l : e.getLocations()) {
            HostGeoInfo hgi = fromLocation(l);
            if (hgi != null)
                return hgi;
        }
        return null;
    }
    
    public static InetAddress findIpAddress(Location l) {
        if (l == null)
            return null;
        if (l instanceof MachineLocation)
            return ((MachineLocation) l).getAddress();
        return findIpAddress(l.getParentLocation());
    }
    
    
    public HostGeoInfo(String address, String displayName, double latitude, double longitude) {
        this.address = address;
        this.displayName = displayName;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return "ServerGeoInfo["+displayName+": "+address+" at ("+latitude+","+longitude+")]";
    }
    
    @Override
    public boolean equals(Object o) {
        // Slight cheat: only tests the address field.
        return (o instanceof HostGeoInfo) && address.equals(((HostGeoInfo) o).address);
    }
    
    @Override
    public int hashCode() {
        // Slight cheat: only includes the address field.
        return address.hashCode();
    }
    
}

@@ -19,24 +19,53 @@
 ntity.dns;%0A%0A
+import java.math.BigDecimal;%0A
 import java.
@@ -537,22 +537,22 @@
         
-Double
+Object
  latitud
@@ -550,33 +550,24 @@
 t latitude =
- (Double)
  l.findLocat
@@ -599,22 +599,22 @@
         
-Double
+Object
  longitu
@@ -621,17 +621,8 @@
 de =
- (Double)
  l.f
@@ -721,36 +721,24 @@
 ude == null)
-%0A           
  return null
@@ -729,32 +729,402 @@
 ull) return null
+;%0A        if (latitude instanceof BigDecimal) latitude = ((BigDecimal) latitude).doubleValue();%0A        if (longitude instanceof BigDecimal) longitude = ((BigDecimal) longitude).doubleValue();%0A        if (!(latitude instanceof Double) %7C%7C !(longitude instanceof Double))%0A            throw new IllegalArgumentException(%22Passed location specifies invalid type of lat/long%22)
 ;%0A        %0A     
@@ -1182,25 +1182,43 @@
 Name(), 
-latitude,
+(Double) latitude, (Double)
  longitu

Accept lat/long coordinates as BigDecimals or Doubles