<commit_before>%% Copyright (c) 2016 <NAME> <<EMAIL>>
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.

-module(haystack_docker).
-behaviour(gen_server).

%% API.
-export([start_link/0]).

%% gen_server.
-export([code_change/3]).
-export([handle_call/3]).
-export([handle_cast/2]).
-export([handle_info/2]).
-export([init/1]).
-export([terminate/2]).

-include_lib("kernel/include/inet.hrl").
-include_lib("public_key/include/public_key.hrl").

%% API.

-export_type([id/0]).

-type id() :: <<_:64>>.

-spec start_link() -> {ok, pid()}.
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).


init([]) ->
    case connection() of
        {ok, #{host := Host,
               port := Port,
               cert := Cert,
               key := Key}} ->

            case gun:open(Host,
                          Port,
                          #{transport => ssl,
                            transport_opts => haystack_docker_util:ssl(Cert,
                                                                       Key)}) of
                {ok, Pid} ->
                    {ok, #{docker => Pid,
                           monitor => monitor(process, Pid),
                           partial => <<>>,
                           host => Host,
                           port => Port,
                           cert => Cert,
                           key => Key}};

                {error, Reason} ->
                    {stop, Reason}
            end;

        {ok, #{host := Host,
               port := Port}} ->

            case gun:open(Host,
                          Port,
                          #{transport => tcp}) of
                {ok, Pid} ->
                    {ok, #{docker => Pid,
                           monitor => monitor(process, Pid),
                           partial => <<>>,
                           host => Host,
                           port => Port}};

                {error, Reason} ->
                    {stop, Reason}
            end;

        {error, Reason} ->
            error_logger:error_report([{module, ?MODULE},
                                       {line, ?LINE},
                                       {reason, Reason}]),
            ignore
    end.

handle_call(_, _, State) ->
    {stop, error, State}.

handle_cast(_, State) ->
    {stop, error, State}.

handle_info({'DOWN', Monitor, process, _, normal},
            #{monitor := Monitor} = State) ->
    {stop, {error, lost_connection}, State};

handle_info({gun_up, Gun, http}, #{docker := Gun} = State) ->
    {noreply,
     State#{
       info => gun:get(Gun, "/info"),
       networks => gun:get(Gun, "/networks"),
       containers => gun:get(Gun, "/containers/json"),
       events => gun:get(Gun, "/events")
      }};

handle_info({gun_down, Gun, http, normal, [], []}, #{docker := Gun} = State) ->
    {noreply, State};

handle_info({gun_data, _, Info, fin, Data},
            #{info := Info,
              partial := Partial,
              host := Host} = State) ->
    #{<<"ID">> := Id,
      <<"SystemTime">> := SystemTime}  = Response = jsx:decode(<<Partial/binary,
                                                                 Data/binary>>,
                                                               [return_maps]),

    StartTime = haystack_date:seconds_since_epoch(
                  haystack_docker_util:system_time(SystemTime)),

    error_logger:info_report([{module, ?MODULE},
                              {line, ?LINE},
                              {response, Response}]),

    case inet:parse_ipv4_address(Host) of
        {ok, Address} ->
            register_docker_a(Id, Address),
            {noreply,
             maps:without([info], State#{id => Id,
                                         start_time => StartTime,<commit_msg>drop unnecessary error_logger:info_report.<commit_after>%% Copyright (c) 2016 <NAME> <<EMAIL>>
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.

-module(haystack_docker).
-behaviour(gen_server).

%% API.
-export([start_link/0]).

%% gen_server.
-export([code_change/3]).
-export([handle_call/3]).
-export([handle_cast/2]).
-export([handle_info/2]).
-export([init/1]).
-export([terminate/2]).

-include_lib("kernel/include/inet.hrl").
-include_lib("public_key/include/public_key.hrl").

%% API.

-export_type([id/0]).

-type id() :: <<_:64>>.

-spec start_link() -> {ok, pid()}.
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).


init([]) ->
    case connection() of
        {ok, #{host := Host,
               port := Port,
               cert := Cert,
               key := Key}} ->

            case gun:open(Host,
                          Port,
                          #{transport => ssl,
                            transport_opts => haystack_docker_util:ssl(Cert,
                                                                       Key)}) of
                {ok, Pid} ->
                    {ok, #{docker => Pid,
                           monitor => monitor(process, Pid),
                           partial => <<>>,
                           host => Host,
                           port => Port,
                           cert => Cert,
                           key => Key}};

                {error, Reason} ->
                    {stop, Reason}
            end;

        {ok, #{host := Host,
               port := Port}} ->

            case gun:open(Host,
                          Port,
                          #{transport => tcp}) of
                {ok, Pid} ->
                    {ok, #{docker => Pid,
                           monitor => monitor(process, Pid),
                           partial => <<>>,
                           host => Host,
                           port => Port}};

                {error, Reason} ->
                    {stop, Reason}
            end;

        {error, Reason} ->
            error_logger:error_report([{module, ?MODULE},
                                       {line, ?LINE},
                                       {reason, Reason}]),
            ignore
    end.

handle_call(_, _, State) ->
    {stop, error, State}.

handle_cast(_, State) ->
    {stop, error, State}.

handle_info({'DOWN', Monitor, process, _, normal},
            #{monitor := Monitor} = State) ->
    {stop, {error, lost_connection}, State};

handle_info({gun_up, Gun, http}, #{docker := Gun} = State) ->
    {noreply,
     State#{
       info => gun:get(Gun, "/info"),
       networks => gun:get(Gun, "/networks"),
       containers => gun:get(Gun, "/containers/json"),
       events => gun:get(Gun, "/events")
      }};

handle_info({gun_down, Gun, http, normal, [], []}, #{docker := Gun} = State) ->
    {noreply, State};

handle_info({gun_data, _, Info, fin, Data},
            #{info := Info,
              partial := Partial,
              host := Host} = State) ->
    #{<<"ID">> := Id,
      <<"SystemTime">> := SystemTime} = jsx:decode(<<Partial/binary,
                                                     Data/binary>>,
                                                   [return_maps]),

    StartTime = haystack_date:seconds_since_epoch(
                  haystack_docker_util:system_time(SystemTime)),

    case inet:parse_ipv4_address(Host) of
        {ok, Address} ->
            register_docker_a(Id, Address),
            {noreply,
             maps:without([info], State#{id => Id,
                                         start_time => StartTime,
{'fraction_non_alphanumeric': 0.146006162597772, 'fraction_numerical': 0.004503436833372837, 'mean_word_length': 1.4531976744186046, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1968162', 'n_tokens_mistral': 2313, 'n_tokens_neox': 2225, 'n_words': 562}