%
% Copyright (c) 2009 SpringSource, Inc.
% Copyright (c) 2010 VMware, Inc.
%
% 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(sigar).

% generated by SigarWrapper.pm
-include("../priv/gen/sigar.hrl").

-export([start/0, stop/1, get_value/2]).

% handrolled wrappers
-export([loadavg/1,
         net_connection_list/2,
         net_interface_list/1,
         net_route_list/1,
         file_system_list/1,
         cpu_info_list/1,
         arp_list/1,
         who_list/1]).

-define(NETCONN_CLIENT, 0x01).
-define(NETCONN_SERVER, 0x02).

-define(SIGAR_NETCONN_TCP,  0x10).
-define(SIGAR_NETCONN_UDP,  0x20).
-define(SIGAR_NETCONN_RAW,  0x40).
-define(SIGAR_NETCONN_UNIX, 0x80).

start() ->
    case load_driver() of
        ok ->
            S = open_port({spawn, 'sigar_drv'}, [binary]),
            {ok, {sigar, S}};
        {error, Err} ->
            Msg = erl_ddll:format_error(Err),
            {error, Msg}
    end.

% handrolled wrappers
loadavg({sigar, S}) ->
    do_command(S, ?LOADAVG).

net_connection_list({sigar, S}, F) ->
    do_command(S, ?NET_CONNECTION_LIST, F).

net_interface_list({sigar, S}) ->
    do_command(S, ?NET_INTERFACE_LIST).

net_route_list({sigar, S}) ->
    do_command(S, ?NET_ROUTE_LIST).

file_system_list({sigar, S}) ->
    do_command(S, ?FILE_SYSTEM_LIST).

cpu_info_list({sigar, S}) ->
    do_command(S, ?CPU_INFO_LIST).

arp_list({sigar, S}) ->
    do_command(S, ?ARP_LIST).

who_list({sigar, S}) ->
    do_command(S, ?WHO_LIST).

% generated by SigarWrapper.pm
-include("../priv/gen/sigar_gen.hrl").

% XXX must be a better way
get_value(Key, List) ->
    case lists:keysearch(Key,1,List) of
      false ->
            1;
        { value, {Key, N} } ->
            N
    end.

stop({sigar, S}) ->
    unlink(S),
    port_close(S).

load_driver() ->
    Dir = filename:join([filename:dirname(code:which(sigar)), "..", "priv"]),
    erl_ddll:load(Dir, "sigar_drv").

do_command(S, C) ->
    port_command(S, [C]),
    receive
        {S, {data, Bin}} -> binary_to_term(Bin)
    end.

do_command(S, C, A) ->
    port_command(S, [C, A]),
    receive
        {S, {data, Bin}} -> binary_to_term(Bin)
    end.
