% 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(couch_log_writer_syslog).
-behavior(couch_log_writer).

-export([
    init/0,
    terminate/2,
    write/2
]).

-include("couch_log.hrl").

-record(st, {
    socket,
    host,
    port,
    hostname,
    os_pid,
    appid,
    facility
}).

-define(SYSLOG_VERSION, 1).

-ifdef(TEST).
-export([
    get_facility/1,
    get_level/1
]).
-endif.

init() ->
    {ok, Socket} = gen_udp:open(0),

    Host =
        case config:get("log", "syslog_host") of
            undefined ->
                undefined;
            SysLogHost ->
                case inet:getaddr(SysLogHost, inet) of
                    {ok, Address} ->
                        Address;
                    _ ->
                        undefined
                end
        end,

    {ok, #st{
        socket = Socket,
        host = Host,
        port = config:get_integer("log", "syslog_port", 514),
        hostname = net_adm:localhost(),
        os_pid = os:getpid(),
        appid = config:get("log", "syslog_appid", "couchdb"),
        facility = get_facility(config:get("log", "syslog_facility", "local2"))
    }}.

terminate(_Reason, St) ->
    gen_udp:close(St#st.socket).

write(Entry, St) ->
    #log_entry{
        level = Level,
        pid = Pid,
        msg = Msg,
        msg_id = MsgId,
        time_stamp = TimeStamp
    } = Entry,
    Fmt = "<~B>~B ~s ~s ~s ~p ~s - ",
    Args = [
        St#st.facility bor get_level(Level),
        ?SYSLOG_VERSION,
        TimeStamp,
        St#st.hostname,
        St#st.appid,
        Pid,
        MsgId
    ],
    Pre = io_lib:format(Fmt, Args),
    ok = send(St, [Pre, Msg, $\n]),
    {ok, St}.

send(#st{host = undefined}, Packet) ->
    io:format(standard_error, "~s", [Packet]);
send(St, Packet) ->
    #st{
        socket = Socket,
        host = Host,
        port = Port
    } = St,
    gen_udp:send(Socket, Host, Port, Packet).

get_facility(Name) ->
    FacId =
        case Name of
            % Kernel messages
            "kern" ->
                0;
            % Random user-level messages
            "user" ->
                1;
            % Mail system
            "mail" ->
                2;
            % System daemons
            "daemon" ->
                3;
            % Security/Authorization messages
            "auth" ->
                4;
            % Internal Syslog messages
            "syslog" ->
                5;
            % Line printer subsystem
            "lpr" ->
                6;
            % Network news subsystems
            "news" ->
                7;
            % UUCP subsystem
            "uucp" ->
                8;
            % Clock daemon
            "clock" ->
                9;
            % Security/Authorization messages
            "authpriv" ->
                10;
            % FTP daemon
            "ftp" ->
                11;
            % NTP subsystem
            "ntp" ->
                12;
            % Log audit
            "audit" ->
                13;
            % Log alert
            "alert" ->
                14;
            % Scheduling daemon
            "cron" ->
                15;
            % Local use 0
            "local0" ->
                16;
            % Local use 1
            "local1" ->
                17;
            % Local use 2
            "local2" ->
                18;
            % Local use 3
            "local3" ->
                19;
            % Local use 4
            "local4" ->
                20;
            % Local use 5
            "local5" ->
                21;
            % Local use 6
            "local6" ->
                22;
            % Local use 7
            "local7" ->
                23;
            _ ->
                try list_to_integer(Name) of
                    N when N >= 0, N =< 23 -> N;
                    _ -> 23
                catch
                    _:_ ->
                        23
                end
        end,
    FacId bsl 3.

get_level(Name) when is_atom(Name) ->
    case Name of
        debug -> 7;
        info -> 6;
        notice -> 5;
        warning -> 4;
        error -> 3;
        critical -> 2;
        alert -> 1;
        emergency -> 0;
        _ -> 3
    end.
