Skip to main content

src/gdav@discover_service.erl

-module(gdav@discover_service).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gdav/discover_service.gleam").
-export([request/1, build/2, response/1]).
-export_type([account_type/0, discovery_result/0, request_builder/0]).

-type account_type() :: cal_d_a_v | card_d_a_v.

-type discovery_result() :: {redirected, binary()} | confirmed.

-type request_builder() :: {request_builder, account_type()}.

-file("src/gdav/discover_service.gleam", 23).
-spec request(account_type()) -> request_builder().
request(Account_type) ->
    {request_builder, Account_type}.

-file("src/gdav/discover_service.gleam", 27).
-spec build(request_builder(), gdav:credentials()) -> gleam@http@request:request(binary()).
build(Builder, Credentials) ->
    Well_known = case erlang:element(2, Builder) of
        cal_d_a_v ->
            <<"/.well-known/caldav"/utf8>>;

        card_d_a_v ->
            <<"/.well-known/carddav"/utf8>>
    end,
    Headers = [{<<"Depth"/utf8>>, <<"0"/utf8>>},
        {<<"Content-Type"/utf8>>, <<"application/xml; charset=utf-8"/utf8>>}],
    Body = <<"<d:propfind xmlns:d=\"DAV:\"><d:prop><d:resourcetype/></d:prop></d:propfind>"/utf8>>,
    gdav@internal:request(
        Credentials,
        {other, <<"PROPFIND"/utf8>>},
        Well_known,
        Headers,
        Body
    ).

-file("src/gdav/discover_service.gleam", 50).
-spec response(gleam@http@response:response(binary())) -> {ok,
        discovery_result()} |
    {error, gdav:dav_error()}.
response(Res) ->
    case erlang:element(2, Res) of
        S when (S >= 300) andalso (S < 400) ->
            case gleam@list:find(
                erlang:element(3, Res),
                fun(H) ->
                    string:lowercase(erlang:element(1, H)) =:= <<"location"/utf8>>
                end
            ) of
                {ok, {_, Url}} ->
                    {ok, {redirected, Url}};

                {error, _} ->
                    {error, {unexpected_response, Res}}
            end;

        S@1 when (S@1 >= 200) andalso (S@1 < 300) ->
            {ok, confirmed};

        _ ->
            {error, {unexpected_response, Res}}
    end.