%% 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";
    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://issues.apache.org/jira/browse/COUCHDB\""},
    {"PACKAGE_NAME", "\"Apache CouchDB\""},
    {"PACKAGE_STRING", "\"Apache CouchDB " ++ Version ++ "\""},
    {"PACKAGE_VERSION", "\"" ++ Version ++ "\""}
],

CouchJSConfig = "priv/couch_js/" ++ SMVsn ++ "/config.h",
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,

{JS_CFLAGS, JS_LDFLAGS} = case os:type() of
    {win32, _} when SMVsn == "1.8.5" ->
        {
            "/DXP_WIN /IC:\\relax\\js-1.8.5\\js\\src",
            "/LIBPATH:C:\\relax\\js-1.8.5\\js\\src 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 /IC:\\relax\\js-60\\js\\src",
            "/LIBPATH:C:\\relax\\js-60\\js\\src 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",
            "-L/usr/local/lib -std=c++14 -lmozjs-60 -lm"
        }
end.

{CURL_CFLAGS, CURL_LDFLAGS} = case lists:keyfind(with_curl, 1, CouchConfig) of
    {with_curl, true} ->
        case os:type() of
            {win32, _} ->
                {
                    "/DHAVE_CURL /IC:\\relax\\curl\\include",
                    "/LIBPATH:C:\\Relax\\curl\\lib\\release-ssl libcurl_imp.lib"
                };
            {unix, freebsd} ->
                {
                    "-DHAVE_CURL -I/usr/local/include",
                    "-DHAVE_CURL -lcurl"
                };
            _ ->
                {
                    "-DHAVE_CURL",
                    "-DHAVE_CURL -lcurl"
                }
        end;
    _ ->
        {"", ""}
end,

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

CouchJSEnv = case SMVsn of
    "1.8.5" ->
        [
            {"CFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
            {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
        ];
    "60" ->
        [
            {"CXXFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
            {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
        ]
end,

IcuPath = "priv/couch_icu_driver.so",
IcuSrc = ["priv/icu_driver/*.c"],
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"},
                {"LDFLAGS", "-L/usr/local/opt/icu4c/lib"}],
IcuBsdEnv = [{"CFLAGS", "-DXP_UNIX -I/usr/local/include"},
             {"LDFLAGS", "-L/usr/local/lib"}],
IcuWinEnv = [{"CFLAGS", "/DXP_WIN /IC:\\relax\\icu\\include"},
             {"LDFLAGS", "/LIBPATH:C:\\relax\\icu\\lib64 icuin.lib icudt.lib icuuc.lib"}],

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

BaseSpecs = [
        %% couchjs
        {".*", CouchJSPath, CouchJSSrc, [{env, CouchJSEnv}]},
        % ICU
        {"darwin", IcuPath, IcuSrc, [{env, IcuEnv ++ IcuDarwinEnv}]},
        {"linux",  IcuPath, IcuSrc, [{env, IcuEnv}]},
        {"bsd",   IcuPath, IcuSrc, [{env, IcuEnv ++ IcuBsdEnv}]},
        {"win32",  IcuPath, IcuSrc, [{env, IcuWinEnv}]},
        % 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"]}
],

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},
        {i, "../"}
    ] ++ MD5Config},
    {eunit_compile_opts, PlatformDefines}
].

lists:foldl(fun({K, V}, CfgAcc) ->
    lists:keystore(K, 1, CfgAcc, {K, V})
end, CONFIG, AddConfig).
