Skip to main content

src/gdav@sync_collection.erl

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

-type sync_result() :: {sync_result,
        list({binary(), binary()}),
        list(binary()),
        binary()}.

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

-file("src/gdav/sync_collection.gleam", 22).
-spec request(binary(), binary()) -> request_builder().
request(Collection_path, Sync_token) ->
    {request_builder, Collection_path, Sync_token}.

-file("src/gdav/sync_collection.gleam", 26).
-spec build(request_builder(), gdav:credentials()) -> gleam@http@request:request(binary()).
build(Builder, Credentials) ->
    Headers = [{<<"Content-Type"/utf8>>,
            <<"application/xml; charset=utf-8"/utf8>>}],
    Body = <<<<<<<<<<<<<<"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"/utf8,
                                "<d:sync-collection xmlns:d=\"DAV:\">"/utf8>>/binary,
                            "<d:sync-token>"/utf8>>/binary,
                        (erlang:element(3, Builder))/binary>>/binary,
                    "</d:sync-token>"/utf8>>/binary,
                "<d:sync-level>1</d:sync-level>"/utf8>>/binary,
            "<d:prop><d:getetag/></d:prop>"/utf8>>/binary,
        "</d:sync-collection>"/utf8>>,
    gdav@internal:request(
        Credentials,
        {other, <<"REPORT"/utf8>>},
        erlang:element(2, Builder),
        Headers,
        Body
    ).

-file("src/gdav/sync_collection.gleam", 50).
-spec response(gleam@http@response:response(binary())) -> {ok, sync_result()} |
    {error, gdav:dav_error()}.
response(Res) ->
    case erlang:element(2, Res) of
        S when (S >= 200) andalso (S < 300) ->
            gleam@result:'try'(
                gdav@internal@xml:parse_sync_report(erlang:element(4, Res)),
                fun(_use0) ->
                    {Responses, Sync_token} = _use0,
                    Changed = gleam@list:filter_map(
                        Responses,
                        fun(R) ->
                            case gdav@internal@xml:find_text(
                                erlang:element(4, R),
                                <<"DAV:"/utf8>>,
                                <<"getetag"/utf8>>
                            ) of
                                {ok, Etag} when Etag =/= <<""/utf8>> ->
                                    {ok, {erlang:element(2, R), Etag}};

                                _ ->
                                    {error, nil}
                            end
                        end
                    ),
                    Deleted = gleam@list:filter_map(
                        Responses,
                        fun(R@1) -> case erlang:element(3, R@1) of
                                404 ->
                                    {ok, erlang:element(2, R@1)};

                                _ ->
                                    {error, nil}
                            end end
                    ),
                    {ok, {sync_result, Changed, Deleted, Sync_token}}
                end
            );

        401 ->
            {error, authentication_failed};

        403 ->
            {error, authentication_failed};

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