<commit_before>%%%-------------------------------------------------------------------
%%% @author <NAME>
%%% @copyright (C) 2019 ACK CYFRONET AGH
%%% This software is released under the MIT license
%%% cited in 'LICENSE.txt'.
%%% @end
%%%-------------------------------------------------------------------
%%% @doc
%%% This module handles translation of middleware results concerning
%%% file entities into REST responses.
%%% @end
%%%-------------------------------------------------------------------
-module(file_rest_translator).
-author("<NAME>").

-include("http/rest.hrl").
-include("middleware/middleware.hrl").
-include("proto/oneprovider/provider_messages.hrl").

-export([create_response/4, get_response/2]).


%%%===================================================================
%%% API
%%%===================================================================


%%--------------------------------------------------------------------
%% @doc
%% {@link rest_translator_behaviour} callback create_response/4.
%% @end
%%--------------------------------------------------------------------
-spec create_response(gri:gri(), middleware:auth_hint(),
    middleware:data_format(), Result :: term() | {gri:gri(), term()} |
    {gri:gri(), middleware:auth_hint(), term()}) -> #rest_resp{}.
create_response(#gri{aspect = object_id}, _, value, ObjectId) ->
    ?OK_REPLY(#{<<"fileId">> => ObjectId});
create_response(#gri{aspect = register_file}, _, value, ObjectId) ->
    ?CREATED_REPLY([<<"data">>, ObjectId],  #{<<"fileId">> => ObjectId}).


%%--------------------------------------------------------------------
%% @doc
%% {@link rest_translator_behaviour} callback get_response/2.
%% @end
%%--------------------------------------------------------------------
-spec get_response(gri:gri(), Resource :: term()) -> #rest_resp{}.
get_response(#gri{aspect = As}, Result) when
    As =:= object_id
->
    ?OK_REPLY(Result);

get_response(#gri{aspect = As}, RdfMetadata) when
    As =:= rdf_metadata;
    As =:= symlink_value
->
    ?OK_REPLY({binary, RdfMetadata});

get_response(#gri{aspect = As}, Metadata) when
    As =:= attrs;
    As =:= distribution;
    As =:= qos_summary;
    As =:= xattrs;
    As =:= json_metadata
->
    ?OK_REPLY(Metadata);

get_response(#gri{aspect = dataset_summary}, #file_eff_dataset_summary{
    direct_dataset = DatasetId,
    eff_ancestor_datasets = EffAncestorDatasets,
    eff_protection_flags = EffProtectionFlags
}) ->
    ?OK_REPLY(#{
        <<"directDataset">> => utils:undefined_to_null(DatasetId),
        <<"effectiveAncestorDatasets">> => EffAncestorDatasets,
        <<"effectiveProtectionFlags">> => file_meta:protection_flags_to_json(EffProtectionFlags)
    });

get_response(#gri{aspect = children}, {Children, IsLast, ReturnedToken}) ->
    ?OK_REPLY(#{
        <<"children">> => Children,
        <<"nextPageToken">> => utils:undefined_to_null(ReturnedToken),
        <<"isLast">> => IsLast
    });

get_response(#gri{aspect = files}, {FilesJson, InaccessiblePaths, NextPageToken}) ->
    ?OK_REPLY(#{
        <<"files">> => FilesJson,
        <<"inaccessiblePaths">> => InaccessiblePaths,
        <<"nextPageToken">> => utils:undefined_to_null(NextPageToken)
    });

get_response(#gri{aspect = hardlinks}, Hardlinks) ->
    ?OK_REPLY(lists:map(fun(FileGuid) ->
        {ok, ObjectId} = file_id:guid_to_objectid(FileGuid),
        ObjectId
    end, Hardlinks));

get_response(#gri{aspect = {hardlinks, _}}, _Result) ->
    ?NO_CONTENT_REPLY;

get_response(#gri{aspect = archive_recall_details}, Result) ->
    ?OK_REPLY(translate_archive_recall_details(Result));

get_response(#gri{aspect = archive_recall_progress}, ArchiveRecallProgress) ->
    ?OK_REPLY(ArchiveRecallProgress).


%%%===================================================================
%%% Internal functions
%%%===================================================================


%% @private
-spec translate_archive_recall_details(archive_recall:record()) -> map().
translate_archive_recall_details(#archive_recall_details{
    archive_id = ArchiveId,
    dataset_id = DatasetId,
    start_timestamp = StartTimestamp,
    finish_timestamp = FinishTimestamp,
    total_file_count = TotalFileCount,
    total_byte_size = TotalByteSize
}) ->
    #{
        <<"archiveId">> => ArchiveId,
        <<"datasetId">> => DatasetId,
        <<"startTime">> => utils:undefined_to_null(StartTimestamp),
        <<"finishTime">> => utils:undefined_to_null(FinishTimestamp),
        <<"totalFileCount">> => TotalFileCount,
        <<"totalByteSize">> => TotalByteSize
    }.<commit_msg>VFS-8644 Added last error to archive recall details rest<commit_after>%%%-------------------------------------------------------------------
%%% @author <NAME>
%%% @copyright (C) 2019 ACK CYFRONET AGH
%%% This software is released under the MIT license
%%% cited in 'LICENSE.txt'.
%%% @end
%%%-------------------------------------------------------------------
%%% @doc
%%% This module handles translation of middleware results concerning
%%% file entities into REST responses.
%%% @end
%%%-------------------------------------------------------------------
-module(file_rest_translator).
-author("<NAME>").

-include("http/rest.hrl").
-include("middleware/middleware.hrl").
-include("proto/oneprovider/provider_messages.hrl").

-export([create_response/4, get_response/2]).


%%%===================================================================
%%% API
%%%===================================================================


%%--------------------------------------------------------------------
%% @doc
%% {@link rest_translator_behaviour} callback create_response/4.
%% @end
%%--------------------------------------------------------------------
-spec create_response(gri:gri(), middleware:auth_hint(),
    middleware:data_format(), Result :: term() | {gri:gri(), term()} |
    {gri:gri(), middleware:auth_hint(), term()}) -> #rest_resp{}.
create_response(#gri{aspect = object_id}, _, value, ObjectId) ->
    ?OK_REPLY(#{<<"fileId">> => ObjectId});
create_response(#gri{aspect = register_file}, _, value, ObjectId) ->
    ?CREATED_REPLY([<<"data">>, ObjectId],  #{<<"fileId">> => ObjectId}).


%%--------------------------------------------------------------------
%% @doc
%% {@link rest_translator_behaviour} callback get_response/2.
%% @end
%%--------------------------------------------------------------------
-spec get_response(gri:gri(), Resource :: term()) -> #rest_resp{}.
get_response(#gri{aspect = As}, Result) when
    As =:= object_id
->
    ?OK_REPLY(Result);

get_response(#gri{aspect = As}, RdfMetadata) when
    As =:= rdf_metadata;
    As =:= symlink_value
->
    ?OK_REPLY({binary, RdfMetadata});

get_response(#gri{aspect = As}, Metadata) when
    As =:= attrs;
    As =:= distribution;
    As =:= qos_summary;
    As =:= xattrs;
    As =:= json_metadata
->
    ?OK_REPLY(Metadata);

get_response(#gri{aspect = dataset_summary}, #file_eff_dataset_summary{
    direct_dataset = DatasetId,
    eff_ancestor_datasets = EffAncestorDatasets,
    eff_protection_flags = EffProtectionFlags
}) ->
    ?OK_REPLY(#{
        <<"directDataset">> => utils:undefined_to_null(DatasetId),
        <<"effectiveAncestorDatasets">> => EffAncestorDatasets,
        <<"effectiveProtectionFlags">> => file_meta:protection_flags_to_json(EffProtectionFlags)
    });

get_response(#gri{aspect = children}, {Children, IsLast, ReturnedToken}) ->
    ?OK_REPLY(#{
        <<"children">> => Children,
        <<"nextPageToken">> => utils:undefined_to_null(ReturnedToken),
        <<"isLast">> => IsLast
    });

get_response(#gri{aspect = files}, {FilesJson, InaccessiblePaths, NextPageToken}) ->
    ?OK_REPLY(#{
        <<"files">> => FilesJson,
        <<"inaccessiblePaths">> => InaccessiblePaths,
        <<"nextPageToken">> => utils:undefined_to_null(NextPageToken)
    });

get_response(#gri{aspect = hardlinks}, Hardlinks) ->
    ?OK_REPLY(lists:map(fun(FileGuid) ->
        {ok, ObjectId} = file_id:guid_to_objectid(FileGuid),
        ObjectId
    end, Hardlinks));

get_response(#gri{aspect = {hardlinks, _}}, _Result) ->
    ?NO_CONTENT_REPLY;

get_response(#gri{aspect = archive_recall_details}, Result) ->
    ?OK_REPLY(translate_archive_recall_details(Result));

get_response(#gri{aspect = archive_recall_progress}, ArchiveRecallProgress) ->
    ?OK_REPLY(ArchiveRecallProgress).


%%%===================================================================
%%% Internal functions
%%%===================================================================


%% @private
-spec translate_archive_recall_details(archive_recall:record()) -> json_utils:json_map().
translate_archive_recall_details(#archive_recall_details{
    archive_id = ArchiveId,
    dataset_id = DatasetId,
    start_timestamp = StartTimestamp,
    finish_timestamp = FinishTimestamp,
    total_file_count = TotalFileCount,
    total_byte_size = TotalByteSize,
    last_error = LastError
}) ->
    #{
        <<"archiveId">> => ArchiveId,
        <<"datasetId">> => DatasetId,
        <<"startTime">> => utils:undefined_to_null(StartTimestamp),
        <<"finishTime">> => utils:undefined_to_null(FinishTimestamp),
        <<"totalFileCount">> => TotalFileCount,
        <<"totalByteSize">> => TotalByteSize,
        <<"lastError">> => case LastError of
            undefined -> null;
            _ -> json_utils:decode(LastError)
        end
    }.
{'fraction_non_alphanumeric': 0.3016362090947726, 'fraction_numerical': 0.0021249468763280916, 'mean_word_length': 2.9700548291859974, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 152, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7053343', 'n_tokens_mistral': 2838, 'n_tokens_neox': 2765, 'n_words': 442}