%{^
#include <curl/curl.h>
%}

absviewtype CURLptr (l:addr) // CURL*
viewtypedef CURLptr0 = [l:addr | l >= null] CURLptr l
viewtypedef CURLptr1 = [l:addr | l >  null] CURLptr l

abst@ype CURLoption = $extype "CURLoption"
macdef CURLOPT_URL = $extval(CURLoption, "CURLOPT_URL")

extern fun curl_easy_init
  ()
  : CURLptr0 = "#curl_easy_init"
extern fun curl_easy_setopt {p:type}
  (handle: !CURLptr1 >> opt(CURLptr1, err == 0), 
   option: CURLoption, parameter: p)
  : #[err:int] int err = "#curl_easy_setopt"
extern fun curl_easy_perform
  (handle: !CURLptr1 >> opt(CURLptr1, err == 0))
  : #[err:int] int err = "#curl_easy_perform"
extern fun curl_easy_cleanup
  (handle: CURLptr1)
  : void = "#curl_easy_cleanup"

extern fun CURLptr_is_null {l:addr}
  (x: !CURLptr l)
  : bool (l == null) = "atspre_ptr_is_null";
extern fun CURLptr_isnot_null {l:addr}
   (x: !CURLptr l)
  : bool (l > null) = "atspre_ptr_isnot_null";

implement main() = let
  val curl = curl_easy_init();
  val () = assert_errmsg(CURLptr_isnot_null curl, "curl_easy_init failed");
  val res = curl_easy_setopt(curl, CURLOPT_URL, "www.bluishcoder.co.nz");
  val () = assert_errmsg(res = 0, "curl_easy_setopt failed");
  prval () = opt_unsome(curl);
  val res = curl_easy_perform(curl);
  val () = assert_errmsg(res = 0, "curl_easy_perform failed");
  prval () = opt_unsome(curl);
  val ()  = curl_easy_cleanup(curl);
in
  ()
end;