% 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_base32).

-export([encode/1, decode/1]).

-define(SET, <<"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567">>).


-spec encode(binary()) -> binary().
encode(Plain) when is_binary(Plain) ->
    IoList = encode(Plain, 0, byte_size(Plain) * 8, []),
    iolist_to_binary(lists:reverse(IoList)).

encode(_Plain, _ByteOffset, 0, Acc) ->
    Acc;

encode(Plain, ByteOffset, BitsRemaining, Acc) when BitsRemaining == 8 ->
    <<A:5, B:3>> = binary:part(Plain, ByteOffset, 1),
    [<<(binary:at(?SET, A)),
       (binary:at(?SET, B bsl 2)),
       "======">> | Acc];

encode(Plain, ByteOffset, BitsRemaining, Acc) when BitsRemaining == 16 ->
    <<A:5, B:5, C:5, D:1>> = binary:part(Plain, ByteOffset, 2),
    [<<(binary:at(?SET, A)),
       (binary:at(?SET, B)),
       (binary:at(?SET, C)),
       (binary:at(?SET, D bsl 4)),
       "====">> | Acc];

encode(Plain, ByteOffset, BitsRemaining, Acc) when BitsRemaining == 24 ->
    <<A:5, B:5, C:5, D:5, E:4>> = binary:part(Plain, ByteOffset, 3),
    [<<(binary:at(?SET, A)),
       (binary:at(?SET, B)),
       (binary:at(?SET, C)),
       (binary:at(?SET, D)),
       (binary:at(?SET, E bsl 1)),
       "===">> | Acc];

encode(Plain, ByteOffset, BitsRemaining, Acc) when BitsRemaining == 32 ->
    <<A:5, B:5, C:5, D:5, E:5, F:5, G:2>> = binary:part(Plain, ByteOffset, 4),
    [<<(binary:at(?SET, A)),
       (binary:at(?SET, B)),
       (binary:at(?SET, C)),
       (binary:at(?SET, D)),
       (binary:at(?SET, E)),
       (binary:at(?SET, F)),
       (binary:at(?SET, G bsl 3)),
       "=">> | Acc];

encode(Plain, ByteOffset, BitsRemaining, Acc) when BitsRemaining >= 40 ->
    <<A:5, B:5, C:5, D:5, E:5, F:5, G:5, H:5>> =
        binary:part(Plain, ByteOffset, 5),
    Output = <<(binary:at(?SET, A)),
               (binary:at(?SET, B)),
               (binary:at(?SET, C)),
               (binary:at(?SET, D)),
               (binary:at(?SET, E)),
               (binary:at(?SET, F)),
               (binary:at(?SET, G)),
               (binary:at(?SET, H))>>,
    encode(Plain, ByteOffset + 5, BitsRemaining  - 40, [Output | Acc]).


-spec decode(binary()) -> binary().
decode(Encoded) when is_binary(Encoded) ->
    IoList = decode(Encoded, 0, []),
    iolist_to_binary(lists:reverse(IoList)).

decode(Encoded, ByteOffset, Acc) when ByteOffset == byte_size(Encoded) ->
    Acc;
decode(Encoded, ByteOffset, Acc) ->
    case binary:part(Encoded, ByteOffset, 8) of
        <<A:1/binary, B:1/binary, "======">> ->
            [<<(find_in_set(A)):5,
               (find_in_set(B) bsr 2):3>> | Acc];
        <<A:1/binary, B:1/binary, C:1/binary, D:1/binary, "====">> ->
            [<<(find_in_set(A)):5,
               (find_in_set(B)):5,
               (find_in_set(C)):5,
               (find_in_set(D) bsr 4):1>> | Acc];
        <<A:1/binary, B:1/binary, C:1/binary, D:1/binary, E:1/binary, "===">> ->
            [<<(find_in_set(A)):5,
               (find_in_set(B)):5,
               (find_in_set(C)):5,
               (find_in_set(D)):5,
               (find_in_set(E) bsr 1):4>> | Acc];
        <<A:1/binary, B:1/binary, C:1/binary, D:1/binary,
          E:1/binary, F:1/binary, G:1/binary, "=">> ->
            [<<(find_in_set(A)):5,
               (find_in_set(B)):5,
               (find_in_set(C)):5,
               (find_in_set(D)):5,
               (find_in_set(E)):5,
               (find_in_set(F)):5,
               (find_in_set(G) bsr 3):2>> | Acc];
        <<A:1/binary, B:1/binary, C:1/binary, D:1/binary,
          E:1/binary, F:1/binary, G:1/binary, H:1/binary>> ->
            decode(Encoded, ByteOffset + 8,
                   [<<(find_in_set(A)):5,
                      (find_in_set(B)):5,
                      (find_in_set(C)):5,
                      (find_in_set(D)):5,
                      (find_in_set(E)):5,
                      (find_in_set(F)):5,
                      (find_in_set(G)):5,
                      (find_in_set(H)):5>> | Acc])
    end.

find_in_set(Char) ->
    case binary:match(?SET, Char) of
        nomatch ->
            erlang:error(not_base32);
        {Offset, _} ->
            Offset
    end.
