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

%
% Blacklist some bad releases.
%
{ok, Version} = file:read_file(filename:join(
    [code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"]
)).

% Version may be binary if file has /n at end :(
% there is no string:trim/1 in Erlang 19 :(
VerString = case Version of
    V when is_binary(V) -> string:strip(binary_to_list(V), right, $\n);
    _ -> string:strip(Version, right, $\n)
end.
VerList = lists:map(fun(X) -> {Int, _} = string:to_integer(X), Int end,
    string:tokens(VerString, ".")).


DisplayMsg = fun(Msg, Args) ->
    Base = iolist_to_binary(io_lib:format(Msg, Args)),
    Lines = binary:split(Base, <<"\n">>, [global]),
    MaxLen = lists:foldl(fun(Line, Acc) ->
        max(Acc, size(Line))
    end, 0, Lines),
    Decoration = iolist_to_binary(["*" || _ <- lists:seq(1, MaxLen)]),
    ReNewLined = [[L, "~n"] || L <- Lines],
    NewLines = ["~n", Decoration, "~n", ReNewLined, Decoration, "~n~n"],
    MsgBin = iolist_to_binary(NewLines),
    io:format(binary_to_list(MsgBin), [])
end.

ErlangTooOld = fun(Ver) ->
    DisplayMsg(
        "This version of Erlang (~p) is too old for use with Apache CouchDB.~n~n"
        "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n"
        "for the latest information on dependencies.",
        [Ver]
    ),
    halt(1)
end.

NotSupported = fun(Ver) ->
    DisplayMsg(
        "This version of Erlang (~p) is not officially supported by Apache~n"
        "CouchDB. While we do not officially support this version, there~n"
        "are also no known bugs or incompatibilities.~n~n"
        "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n"
        "for the latest information on dependencies.",
        [Ver]
    )
end.

BadErlang = fun(Ver) ->
    DisplayMsg(
        "This version of Erlang (~p) is known to contain bugs that directly~n"
        "affect the correctness of Apache CouchDB.~n~n"
        "You should *NOT* use this version of Erlang.~n~n"
        "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n"
        "for the latest information on dependencies.",
        [Ver]
    ),
    case os:getenv("TRAVIS") of
        "true" ->
            io:fwrite("Travis run, ignoring bad release. You have been warned!~n"),
            ok;
        _ ->
            halt(1)
    end
end.

case VerList of
    [OldVer | _] when OldVer < 19 -> ErlangTooOld(VerString);

    [19 | _] -> NotSupported(VerString);

    [20 | _] = V20 when V20 < [20, 3, 8, 11] -> BadErlang(VerString);
    [21 | _] = V21 when V21 < [21, 2, 3] -> BadErlang(VerString);
    [22, 0, N | _] when N < 5 -> BadErlang(VerString);

    _ -> ok
end.

% Set the path to the configuration environment generated
% by `./configure`.

COUCHDB_ROOT = filename:dirname(SCRIPT).
os:putenv("COUCHDB_ROOT", COUCHDB_ROOT).

ConfigureEnv = filename:join(COUCHDB_ROOT, "config.erl").
os:putenv("COUCHDB_CONFIG", ConfigureEnv).

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

os:putenv("COUCHDB_APPS_CONFIG_DIR", filename:join([COUCHDB_ROOT, "rel/apps"])).

SubDirs = [
    %% must be compiled first as it has a custom behavior
    "src/couch_epi",
    "src/couch_log",
    "src/chttpd",
    "src/couch",
    "src/couch_eval",
    "src/couch_event",
    "src/mem3",
    "src/couch_index",
    "src/couch_mrview",
    "src/couch_js",
    "src/couch_replicator",
    "src/couch_plugins",
    "src/couch_pse_tests",
    "src/couch_stats",
    "src/couch_peruser",
    "src/couch_tests",
    "src/couch_views",
    "src/ctrace",
    "src/ddoc_cache",
    "src/dreyfus",
    "src/fabric",
    "src/aegis",
    "src/couch_jobs",
    "src/couch_expiring_cache",
    "src/global_changes",
    "src/ioq",
    "src/jwtf",
    "src/ken",
    "src/mango",
    "src/rexi",
    "src/setup",
    "src/smoosh",
    "src/ebtree",
    "rel"
].

DepDescs = [
%% Independent Apps
{config,           "config",           {tag, "2.1.8"}},
{b64url,           "b64url",           {tag, "1.0.2"}},
{erlfdb,           "erlfdb",           {tag, "v1.2.3"}},
{ets_lru,          "ets-lru",          {tag, "1.1.0"}},
{khash,            "khash",            {tag, "1.1.0"}},
{snappy,           "snappy",           {tag, "CouchDB-1.0.4"}},

%% Non-Erlang deps
{docs,             {url, "https://github.com/apache/couchdb-documentation"},
                   {tag, "3.1.0-RC1"}, [raw]},
{fauxton,          {url, "https://github.com/apache/couchdb-fauxton"},
                   {tag, "v1.2.6"}, [raw]},
%% Third party deps
{folsom,           "folsom",           {tag, "CouchDB-0.8.3"}},
{hyper,            "hyper",            {tag, "CouchDB-2.2.0-6"}},
{ibrowse,          "ibrowse",          {tag, "CouchDB-4.0.1-2"}},
{jaeger_passage,   "jaeger-passage",   {tag, "CouchDB-0.1.14-1"}},
{jiffy,            "jiffy",            {tag, "CouchDB-1.0.4-1"}},
{local,            "local",            {tag, "0.2.1"}},
{mochiweb,         "mochiweb",         {tag, "v2.20.0"}},
{meck,             "meck",             {tag, "0.8.8"}},
{recon,            "recon",            {tag, "2.5.0"}},
{passage,          "passage",          {tag, "0.2.6"}},
{thrift_protocol,  "thrift-protocol",  {tag, "0.1.5"}}
].

WithProper = lists:keyfind(with_proper, 1, CouchConfig) == {with_proper, true}.

OptionalDeps = case WithProper of
    true ->
        [{proper, {url, "https://github.com/proper-testing/proper"}, {tag, "v1.3"}}];
    false ->
        []
end.

BaseUrl = "https://github.com/apache/".

MakeDep = fun
    ({AppName, {url, Url}, Version}) ->
        {AppName, ".*", {git, Url, Version}};
    ({AppName, {url, Url}, Version, Options}) ->
        {AppName, ".*", {git, Url, Version}, Options};
    ({AppName, RepoName, Version}) ->
        Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git",
        {AppName, ".*", {git, Url, Version}};
    ({AppName, RepoName, Version, Options}) ->
        Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git",
        {AppName, ".*", {git, Url, Version}, Options}
end.

ErlOpts = case os:getenv("ERL_OPTS") of
    false -> [];
    Opts -> [list_to_atom(O) || O <- string:tokens(Opts, ",")]
end.

AddConfig = [
    {require_otp_vsn, "19|20|21|22"},
    {deps_dir, "src"},
    {deps, lists:map(MakeDep, DepDescs ++ OptionalDeps)},
    {sub_dirs, SubDirs},
    {lib_dirs, ["src"]},
    {erl_opts, [{i, "../"} | ErlOpts]},
    {eunit_opts, [verbose, {report,{eunit_surefire,[{dir,"."}]}}]},
    {plugins, [eunit_plugin]},
    {dialyzer, [
        {plt_location, local},
        {plt_location, COUCHDB_ROOT},
        {plt_extra_apps, [
            asn1, compiler, crypto, inets, kernel, runtime_tools,
            sasl, setup, ssl, stdlib, syntax_tools, xmerl]},
        {warnings, [unmatched_returns, error_handling, race_conditions]}]},
    {post_hooks, [{compile, "escript support/build_js.escript"}]}
].

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