///|
extern "js" fn _resolve_hostname_ffi(host : String, cb: (String, Int) -> Bool) -> Bool =
  #| function(host, cb) {
  #|   const dns = require('dns');
  #|   try {
  #|     let terminated = false;
  #|     dns.lookup(host, {all: true}, (err, addresses) => {
  #|       if (err) {
  #|         return;
  #|       }
  #|       console.log("Resolved addresses for \{host}: \{addresses}");
  #|       for (const address of addresses) {
  #|           let addr = address.address;
  #|           let family = address.family;
  #|           terminated = cb(addr, family);
  #|           if (terminated) {
  #|             break;
  #|           }
  #|       }
  #|     });
  #|     return terminated;
  #|   } catch (e) {
  #|     console.error("Error resolving hostname: " + e);
  #|     return true;
  #|   }
  #| }
  #|

///|
pub impl ToSocketAddrs for String with to_socket_addr(self : String) -> Iter[
  SocketAddr
] raise NetError {
  if parse_address(self) is Ok(addr) {
    return [addr].iter()
  }
  let (host, port) = match self.rev_find(":") {
    Some(idx) => {
      let host = self
        .charcodes(end=self.offset_of_nth_char(idx).unwrap())
        .to_string()
      let port_str = self
        .charcodes(start=self.offset_of_nth_char(idx + 1).unwrap())
        .to_string()
      match parse_port(port_str) {
        Ok(port) => (host, port)
        Err(e) => raise NetError(e)
      }
    }
    None => (self, 80) // No port specified, default to 80
  }
  Iter::new(fn(yield_ : (SocketAddr) -> IterResult) {
   if _resolve_hostname_ffi(host, fn(addr : String, family : Int) {
      let res = match family {
        4 => V4(addr, port)
        _ => V6(addr, port, flowinfo=0, scope_id=0)
      }
      match yield_(res) {
        IterEnd => true
        IterContinue => false
      }
    }){
      return IterEnd
    } else {
      return IterContinue
    }
  })
}