% 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_js_tests).
-include_lib("eunit/include/eunit.hrl").

couch_js_test_() ->
    {
        "Test couchjs",
        {
            setup,
            fun test_util:start_couch/0,
            fun test_util:stop_couch/1,
            [
                fun should_create_sandbox/0,
                fun should_roundtrip_utf8/0,
                fun should_roundtrip_modified_utf8/0,
                fun should_replace_broken_utf16/0,
                fun should_allow_js_string_mutations/0,
                {timeout, 60000, fun should_exit_on_oom/0}
            ]
        }
    }.

should_create_sandbox() ->
    % Try and detect whether we can see out of the
    % sandbox or not.
    Src = <<
        "function(doc) {\n"
        "  try {\n"
        "    emit(false, typeof(Couch.compile_function));\n"
        "  } catch (e) {\n"
        "    emit(true, e.message);\n"
        "  }\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
    Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, <<"{}">>]),
    ?assertEqual([[[true, <<"Couch is not defined">>]]], Result).

should_roundtrip_utf8() ->
    % Try round tripping UTF-8 both directions through
    % couchjs. These tests use hex encoded values of
    % Ä (C384) and Ü (C39C) so as to avoid odd editor/Erlang encoding
    % strangeness.
    Src = <<
        "function(doc) {\n"
        "  emit(doc.value, \"",
        16#C3,
        16#9C,
        "\");\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
    Doc =
        {[
            {<<"value">>, <<16#C3, 16#84>>}
        ]},
    Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
    ?assertEqual([[[<<16#C3, 16#84>>, <<16#C3, 16#9C>>]]], Result).

should_roundtrip_modified_utf8() ->
    % Mimicing the test case from the mailing list
    Src = <<
        "function(doc) {\n"
        "  emit(doc.value.toLowerCase(), \"",
        16#C3,
        16#9C,
        "\");\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
    Doc =
        {[
            {<<"value">>, <<16#C3, 16#84>>}
        ]},
    Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
    ?assertEqual([[[<<16#C3, 16#A4>>, <<16#C3, 16#9C>>]]], Result).

should_replace_broken_utf16() ->
    % This test reverse the surrogate pair of
    % the Boom emoji U+1F4A5
    Src = <<
        "function(doc) {\n"
        "  emit(doc.value.split(\"\").reverse().join(\"\"), 1);\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
    Doc =
        {[
            {<<"value">>, list_to_binary(xmerl_ucs:to_utf8([16#1F4A5]))}
        ]},
    Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
    % Invalid UTF-8 gets replaced with the 16#FFFD replacement
    % marker
    Markers = list_to_binary(xmerl_ucs:to_utf8([16#FFFD, 16#FFFD])),
    ?assertEqual([[[Markers, 1]]], Result).

should_allow_js_string_mutations() ->
    % This binary corresponds to this string: мама мыла раму
    % Which I'm told translates to: "mom was washing the frame"
    MomWashedTheFrame = <<
        16#D0,
        16#BC,
        16#D0,
        16#B0,
        16#D0,
        16#BC,
        16#D0,
        16#B0,
        16#20,
        16#D0,
        16#BC,
        16#D1,
        16#8B,
        16#D0,
        16#BB,
        16#D0,
        16#B0,
        16#20,
        16#D1,
        16#80,
        16#D0,
        16#B0,
        16#D0,
        16#BC,
        16#D1,
        16#83
    >>,
    Mom = <<16#D0, 16#BC, 16#D0, 16#B0, 16#D0, 16#BC, 16#D0, 16#B0>>,
    Washed = <<16#D0, 16#BC, 16#D1, 16#8B, 16#D0, 16#BB, 16#D0, 16#B0>>,
    Src1 = <<
        "function(doc) {\n"
        "  emit(\"length\", doc.value.length);\n"
        "}\n"
    >>,
    Src2 = <<
        "function(doc) {\n"
        "  emit(\"substring\", doc.value.substring(5, 9));\n"
        "}\n"
    >>,
    Src3 = <<
        "function(doc) {\n"
        "  emit(\"slice\", doc.value.slice(0, 4));\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src1]),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src2]),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src3]),
    Doc = {[{<<"value">>, MomWashedTheFrame}]},
    Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
    Expect = [
        [[<<"length">>, 14]],
        [[<<"substring">>, Washed]],
        [[<<"slice">>, Mom]]
    ],
    ?assertEqual(Expect, Result).

should_exit_on_oom() ->
    Src = <<
        "var state = [];\n"
        "function(doc) {\n"
        "  var val = \"0123456789ABCDEF\";\n"
        "  for(var i = 0; i < 665535; i++) {\n"
        "    state.push([val, val]);\n"
        "    emit(null, null);\n"
        "  }\n"
        "}\n"
    >>,
    Proc = couch_query_servers:get_os_process(<<"javascript">>),
    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
    trigger_oom(Proc).

trigger_oom(Proc) ->
    Status =
        try
            couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, <<"{}">>]),
            continue
        catch
            throw:{os_process_error, {exit_status, 1}} ->
                done
        end,
    case Status of
        continue -> trigger_oom(Proc);
        done -> ok
    end.
