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

CopyIfDifferent = fun(Path, Contents) ->
    case filelib:is_file(Path) of
        true ->
            case file:read_file(Path) of
                {ok, Contents} ->
                    ok;
                _ ->
                    file:write_file(Path, Contents)
            end;
        false ->
            file:write_file(Path, Contents)
    end
end.


CouchJSName = case os:type() of
    {win32, _} ->
        "couchjs.exe";
    _ ->
        "couchjs"
end.
CouchJSPath = filename:join(["priv", CouchJSName]).
Version = case os:getenv("COUCHDB_VERSION") of
    false ->
        string:strip(os:cmd("git describe --always"), right, $\n);
    Version0 ->
        string:strip(Version0, right)
end.

GitSha = case os:getenv("COUCHDB_GIT_SHA") of
    false ->
        ""; % release builds won\'t get a fallback
    GitSha0 ->
        string:strip(GitSha0, right)
end.

CouchConfig = case filelib:is_file(os:getenv("COUCHDB_CONFIG")) of
    true ->
        {ok, Result} = file:consult(os:getenv("COUCHDB_CONFIG")),
        Result;
    false ->
        []
end.

SMVsn = case lists:keyfind(spidermonkey_version, 1, CouchConfig) of
    {_, "1.8.5"} ->
        "1.8.5";
    {_, "60"} ->
        "60";
    {_, "68"} ->
        "68";
    {_, "78"} ->
        "78";
    {_, "86"} ->
        "86";
    {_, "91"} ->
        "91";
    undefined ->
        "1.8.5";
    {_, Unsupported} ->
        io:format(standard_error, "Unsupported SpiderMonkey version: ~s~n", [Unsupported]),
        erlang:halt(1);
    false ->
        "1.8.5"
end.

ConfigH = [
    {"SM185", ""},
    {"HAVE_JS_GET_STRING_CHARS_AND_LENGTH", "1"},
    {"JSSCRIPT_TYPE", "JSObject*"},
    {"COUCHJS_NAME", "\"" ++ CouchJSName++ "\""},
    {"PACKAGE", "\"apache-couchdb\""},
    {"PACKAGE_BUGREPORT", "\"https://github.com/apache/couchdb/issues\""},
    {"PACKAGE_NAME", "\"Apache CouchDB\""},
    {"PACKAGE_STRING", "\"Apache CouchDB " ++ Version ++ "\""},
    {"PACKAGE_VERSION", "\"" ++ Version ++ "\""}
].

CouchJSConfig = case SMVsn of
    "78" ->
        "priv/couch_js/86/config.h";
    "91" ->
        "priv/couch_js/86/config.h";
    _ ->
        "priv/couch_js/" ++ SMVsn ++ "/config.h"
end.
ConfigSrc = [["#define ", K, " ", V, $\n] || {K, V} <- ConfigH].
ConfigBin = iolist_to_binary(ConfigSrc).
ok = CopyIfDifferent(CouchJSConfig, ConfigBin).

MD5Config = case lists:keyfind(erlang_md5, 1, CouchConfig) of
    {erlang_md5, true} ->
        [{d, 'ERLANG_MD5', true}];
    _ ->
        []
end.

ProperConfig = case code:lib_dir(proper) of
    {error, bad_name} -> [];
    _ -> [{d, 'WITH_PROPER'}]
end.

{JS_CFLAGS, JS_LDFLAGS} = case os:type() of
    {win32, _} when SMVsn == "1.8.5" ->
        {
            "/DXP_WIN",
            "mozjs185-1.0.lib"
        };
    {unix, _} when SMVsn == "1.8.5" ->
        {
            "-DXP_UNIX -I/usr/include/js -I/usr/local/include/js",
            "-L/usr/local/lib -lmozjs185 -lm"
        };
    {win32, _} when SMVsn == "60" ->
        {
            "/DXP_WIN",
            "mozjs-60.lib"
        };
    {unix, darwin} when SMVsn == "60" ->
        {
            "-DXP_UNIX -I/usr/include/mozjs-60 -I/usr/local/include/mozjs-60 -std=c++14",
            "-L/usr/local/lib -lmozjs-60 -lm -std=c++14 -lc++"
        };
    {unix, _} when SMVsn == "60" ->
        {
            "-DXP_UNIX -I/usr/include/mozjs-60 -I/usr/local/include/mozjs-60 -std=c++14 -Wno-invalid-offsetof",
            "-L/usr/local/lib -std=c++14 -lmozjs-60 -lm"
        };
    {unix, _} when SMVsn == "68" ->
        {
            "-DXP_UNIX -I/usr/include/mozjs-68 -I/usr/local/include/mozjs-68 -std=c++14 -Wno-invalid-offsetof",
            "-L/usr/local/lib -std=c++14 -lmozjs-68 -lm"
        };
    {unix, _} when SMVsn == "78" ->
        {
            "-DXP_UNIX -I/usr/include/mozjs-78 -I/usr/local/include/mozjs-78 -std=c++17 -Wno-invalid-offsetof",
            "-L/usr/local/lib -std=c++17 -lmozjs-78 -lm"
        };
    {unix, _} when SMVsn == "86" ->
        {
            "-DXP_UNIX -I/usr/include/mozjs-86 -I/usr/local/include/mozjs-86 -I/opt/homebrew/include/mozjs-86/ -std=c++17 -Wno-invalid-offsetof",
            "-L/usr/local/lib -L /opt/homebrew/lib/ -std=c++17 -lmozjs-86 -lm"
        };
    {unix, _} when SMVsn == "91" ->
        {
            "$CFLAGS -DXP_UNIX -I/usr/include/mozjs-91 -I/usr/local/include/mozjs-91 -I/opt/homebrew/include/mozjs-91/ -std=c++17 -Wno-invalid-offsetof",
            "$LDFLAGS -L/usr/local/lib -L /opt/homebrew/lib/ -std=c++17 -lmozjs-91 -lm"
        };
    {win32, _} when SMVsn == "91" ->
        {
            "/std:c++17 /DXP_WIN",
            "$LDFLAGS mozjs-91.lib"
        }
end.

CouchJSSrc = case SMVsn of
    "1.8.5" -> ["priv/couch_js/1.8.5/*.c"];
    "60" -> ["priv/couch_js/60/*.cpp"];
    "68" -> ["priv/couch_js/68/*.cpp"];
    "78" -> ["priv/couch_js/86/*.cpp"];
    "86" -> ["priv/couch_js/86/*.cpp"];
    "91" -> ["priv/couch_js/86/*.cpp"]
end.

CouchJSEnv = case SMVsn of
    "1.8.5" ->
        [
            {"CFLAGS", JS_CFLAGS},
            {"LDFLAGS", JS_LDFLAGS}
        ];
    _ ->
        [
            {"CXXFLAGS", JS_CFLAGS},
            {"LDFLAGS", JS_LDFLAGS}
        ]
end.

IcuEnv = [{"DRV_CFLAGS",  "$DRV_CFLAGS -DPIC -O2 -fno-common"},
          {"DRV_LDFLAGS", "$DRV_LDFLAGS -lm -licuuc -licudata -licui18n -lpthread"}].
IcuDarwinEnv = [{"CFLAGS", "-DXP_UNIX -I/usr/local/opt/icu4c/include -I/opt/homebrew/opt/icu4c/include"},
                {"LDFLAGS", "-L/usr/local/opt/icu4c/lib -L/opt/homebrew/opt/icu4c/lib"}].
IcuBsdEnv = [{"CFLAGS", "-DXP_UNIX -I/usr/local/include"},
             {"LDFLAGS", "-L/usr/local/lib"}].
IcuWinEnv = [{"CFLAGS", "$DRV_CFLAGS /DXP_WIN"},
             {"LDFLAGS", "$LDFLAGS icuin.lib icudt.lib icuuc.lib"}].

ComparePath = "priv/couch_ejson_compare.so".
CompareSrc = ["priv/couch_ejson_compare/*.c"].

BaseSpecs = [
        %% couchjs
        {".*", CouchJSPath, CouchJSSrc, [{env, CouchJSEnv}]},
        % ejson_compare
        {"darwin", ComparePath, CompareSrc, [{env, IcuEnv ++ IcuDarwinEnv}]},
        {"linux",  ComparePath, CompareSrc, [{env, IcuEnv}]},
        {"bsd",   ComparePath, CompareSrc, [{env, IcuEnv ++ IcuBsdEnv}]},
        {"win32",  ComparePath, CompareSrc, [{env, IcuWinEnv}]}
].

SpawnSpec = [
    {"priv/couchspawnkillable", ["priv/spawnkillable/*.c"]}
].

%% hack required until switch to enc/rebar3
PortEnvOverrides = [
    {"win32", "EXE_LINK_CXX_TEMPLATE",
    "$LINKER $PORT_IN_FILES $LDFLAGS $EXE_LDFLAGS /OUT:$PORT_OUT_FILE"}
].

PortSpecs = case os:type() of
    {win32, _} ->
        BaseSpecs ++ SpawnSpec;
    _ ->
        {ok, CSK} = file:read_file("priv/spawnkillable/couchspawnkillable.sh"),
        ok = CopyIfDifferent("priv/couchspawnkillable", CSK),
        os:cmd("chmod +x priv/couchspawnkillable"),
        BaseSpecs
end.
PlatformDefines = [
   {platform_define, "win32", 'WINDOWS'}
].
AddConfig = [
    {port_specs, PortSpecs},
    {erl_opts, PlatformDefines ++ [
        {d, 'COUCHDB_VERSION', Version},
        {d, 'COUCHDB_GIT_SHA', GitSha},
        {d, 'COUCHDB_SPIDERMONKEY_VERSION', SMVsn},
        {i, "../"}
    ] ++ MD5Config ++ ProperConfig},
    {port_env, PortEnvOverrides},
    {eunit_compile_opts, PlatformDefines}
].

lists:foldl(fun({K, V}, CfgAcc) ->
    case lists:keyfind(K, 1, CfgAcc) of
        {K, Existent} when is_list(Existent) andalso is_list(V) ->
            lists:keystore(K, 1, CfgAcc, {K, Existent ++ V});
        false ->
            lists:keystore(K, 1, CfgAcc, {K, V})
    end
end, CONFIG, AddConfig).
