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

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

CouchConfig = case filelib:is_file(os:getenv("COUCHDB_CONFIG")) of
    true ->
        {ok, Result} = file:consult(os:getenv("COUCHDB_CONFIG")),
        Result;
    false ->
        []
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 ++ "\""}
],

ConfigSrc = [["#define ", K, " ", V, $\n] || {K, V} <- ConfigH],
ok = file:write_file("priv/couch_js/config.h", ConfigSrc),

{JS_CFLAGS, JS_LDFLAGS} = case lists:keyfind(with_curl, 1, CouchConfig) of
    {with_curl, true} ->
        {"-DHAVE_CURL ", "-DHAVE_CURL -lmozjs185 -lcurl"};
    _ ->
        {"", "-lmozjs185"}
end,

CouchJSSrc = ["priv/couch_js/*.c"],

BaseSpecs = [
        %% couchjs
        {"darwin", CouchJSPath, CouchJSSrc, [{env, [{"CFLAGS", JS_CFLAGS ++ "-DXP_UNIX -I/usr/local/include/js"}, {"LDFLAGS", JS_LDFLAGS}]}]},
        {"linux",  CouchJSPath, CouchJSSrc, [{env, [{"CFLAGS", JS_CFLAGS ++ "-DXP_UNIX -I/usr/include/js"}, {"LDFLAGS", JS_LDFLAGS ++ " -lm"}]}]},
        {"unix",   CouchJSPath, CouchJSSrc, [{env, [{"CFLAGS", JS_CFLAGS ++ "-DXP_UNIX -I/usr/local/include/js}"}, {"LDFLAGS", JS_LDFLAGS ++ " -lm"}]}]},
        {"win32",  CouchJSPath, CouchJSSrc, [{env, [{"CFLAGS", JS_CFLAGS ++ "-DXP_WIN -I/usr/include/js"}, {"LDFLAGS", JS_LDFLAGS}]}]},
        % ICU
        {"", "priv/couch_icu_driver.so", ["priv/icu_driver/*.c"], [{env, [
            {"DRV_CFLAGS",  "$DRV_CFLAGS -DPIC -O2 -fno-common"},
            {"DRV_LDFLAGS", "$DRV_LDFLAGS -lm -licuuc -licudata -licui18n -lpthread"}]}]},
        % ejson_compare
        {"priv/couch_ejson_compare.so", ["priv/couch_ejson_compare/*.c"]}
],

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

PortSpecs = case os:type() of
    {win32, _} ->
        BaseSpecs ++ SpawnSpec;
    _ ->
        {ok, _} = file:copy("priv/spawnkillable/couchspawnkillable.sh",
                            "priv/couchspawnkillable"),
        os:cmd("chmod +x priv/couchspawnkillable"),
        BaseSpecs
end,

AddConfig = [{port_specs, PortSpecs}].

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

