%% -*- mode: erlang -*-
%% Macula HTTP/3 Mesh - Root Rebar3 Configuration

{erl_opts, [
    debug_info,
    warnings_as_errors,
    warn_export_vars,
    warn_unused_vars,
    warn_obsolete_guard
]}.

%% Include subdirectories in src/ for compilation. Each slice
%% directory holds modules for a coherent capability — see
%% PLAN_V2_PARITY § 3 for the layout rationale. Foundational
%% primitives (macula_id, macula_realm, macula_topic, etc.) stay
%% flat at src/ root; capability slices live in subdirs.
{src_dirs, [
    "src",
    "src/auth",
    "src/client",
    "src/identity",
    "src/macula_cert_system",
    "src/macula_dist_system",
    "src/macula_yggdrasil",
    "src/mri",
    "src/observability",
    "src/peering",
    "src/pubsub",
    "src/record",
    "src/v1",
    %% macula-net L3 substrate (PLAN_MACULA_NET.md)
    "src/derive_address",
    "src/manage_tun_device",
    "src/route_packet",
    "src/deliver_packet",
    "src/macula_net",
    %% Phase 2 — DHT-backed station resolution.
    "src/advertise_station",
    "src/resolve_address",
    "src/cache_route",
    %% Phase 3 — hosted-identity gateway.
    "src/host_identity",
    "src/attach_identity",
    "src/host_attach_controller"
]}.

{pre_hooks, [
    {compile, "sh -c 'B=\"${REBAR_DEPS_DIR}/macula\"; [ -f \"$B/priv/build-nifs.sh\" ] || B=\".\"; sh \"$B/priv/build-nifs.sh\" \"$B\"'"}
]}.

{deps, [
    %% QUIC transport: Quinn via Rust NIF (replaces quicer/MsQuic)
    %% Built from native/macula_quic/ via cargo pre_hooks above

    %% MessagePack serialization
    %% (msgpack removed in v3.0.0 — wire protocol switched to CBOR
    %%  via macula_cbor / macula_cbor_nif Rust NIF.)

    %% Process registry
    {gproc, "0.9.1"},

    %% mDNS local discovery (optional - hex.pm package)
    {macula_mdns, "0.1.0"},

    %% Telemetry for observability and metrics
    {telemetry, "1.3.0"}

    %% JSON encoding: Using built-in json module (OTP 27+)

    %% Crypto, UCAN, DID, MRI NIFs: Built from native/ via Rust/Cargo
    %% (absorbed from macula-nifs package in v1.0)
    %% Falls back to pure Erlang when Rust toolchain not available

    %% Note: Ra/Raft was removed in v0.14.0
    %% Macula uses CRDTs (macula_crdt.erl) for masterless state management
    %% See architecture/ROADMAP.md for details
]}.

{project_plugins, [
    rebar3_hex,
    rebar3_proper,
    rebar3_ex_doc
]}.

%% Test configuration
{eunit_opts, [
    verbose,
    {dir, "test"},
    {dir, "test/macula_dist_system"}
]}.

{cover_enabled, true}.
{cover_opts, [verbose]}.
{cover_excl_mods, []}.  %% Modules to exclude from coverage (e.g., generated code)
{cover_print_enabled, true}.
{cover_export_enabled, true}.

{ct_opts, [
    {sys_config, "config/test.sys.config"}
]}.

{dialyzer, [
    {warnings, [
        no_return,
        no_unused,
        no_improper_lists,
        no_fun_app,
        no_match,
        no_opaque,
        no_fail_call,
        error_handling
    ]},
    {plt_apps, top_level_deps},
    %% macula_mdns: pulled in transitively but its modules are
    %% referenced by macula_dist_discovery (mdns_advertise_sup,
    %% mdns_advertise) — explicit listing teaches dialyzer about them.
    {plt_extra_apps, [macula_mdns]},
    {plt_location, local},
    {base_plt_apps, [erts, kernel, stdlib, crypto, public_key, ssl]},
    {base_plt_location, global}
]}.

%% Shell configuration
{shell, [
    {apps, [macula]},
    {config, "config/sys.config"}
]}.

%% Release configuration
{relx, [
    {release, {macula, "3.0.0"}, [
        macula,
        sasl,
        runtime_tools
        %% observer - removed for headless deployments (requires wx/OpenGL)
    ]},

    {mode, dev},
    {include_erts, true},
    {extended_start_script, true},

    {sys_config, "./config/sys.config"},
    {vm_args, "./config/vm.args"},

    {overlay, [
        {mkdir, "log"},
        {mkdir, "data"},
        {copy, "README.md", "README.md"},
        {copy, "LICENSE", "LICENSE"}
    ]}
]}.

%% Profiles
{profiles, [
    {test, [
        {deps, [
            {proper, "1.4.0"},
            {meck, "0.9.2"}
        ]},
        {erl_opts, [nowarn_export_all]},
        {extra_src_dirs, [
            "test",
            "test/macula_dist_system",
            "bench"
        ]}
    ]},

    {prod, [
        {erl_opts, [
            no_debug_info,
            deterministic
        ]},
        {relx, [
            {mode, prod},
            {dev_mode, false},
            {include_src, false}
        ]}
    ]},

    {lint, [
        {plugins, [
            {rebar3_lint, "5.0.4"}
        ]}
    ]}
]}.

%% Elvis style rules — shared macula_min ruleset (mirrors evoq/reckon-db).
%% Targets deep nesting, nested try/catch, if-expressions. Run `rebar3 lint`.
{elvis, [
    {rulesets, #{
        macula_min => [
            {elvis_style, no_deep_nesting, #{level => 2}},
            {elvis_style, no_nested_try_catch, #{}},
            {elvis_style, no_if_expression, #{}}
        ]
    }},
    {config, [
        #{files => ["src/**/*.erl"], ruleset => macula_min}
    ]}
]}.

%% Documentation
{ex_doc, [
    {extras, [
        {"README.md", #{title => "Overview"}},
        {"CHANGELOG.md", #{title => "Changelog"}},
        %% CHANGELOG_LEGACY.md (pre-3.0) is shipped in the hex package
        %% but intentionally NOT rendered in ex_doc — legacy entries
        %% predate the 3.0 wire-format cutover and use EDoc-style
        %% formatting that doesn't round-trip cleanly through ex_doc's
        %% Markdown parser. View the raw file on Codeberg if you need
        %% pre-3.0 history.
        {"LICENSE", #{title => "License"}},
        {"docs/GLOSSARY.md", #{title => "Glossary"}},
        %% SDK Guides
        {"docs/guides/CONNECTING_GUIDE.md", #{title => "Connecting"}},
        {"docs/guides/PUBSUB_GUIDE.md", #{title => "PubSub Guide"}},
        {"docs/guides/TOPIC_NAMING_GUIDE.md", #{title => "Topic Naming Convention"}},
        {"docs/guides/RPC_GUIDE.md", #{title => "RPC Guide"}},
        {"docs/guides/DIST_OVER_MESH_GUIDE.md", #{title => "Distribution Over Mesh"}},
        {"docs/guides/CLUSTERING_GUIDE.md", #{title => "Clustering"}},
        {"docs/guides/AUTHORIZATION_GUIDE.md", #{title => "Authorization (UCAN/DID)"}},
        {"docs/guides/PROTOCOL_GATEKEEPER_GUIDE.md", #{title => "Protocol Gatekeeper"}},
        {"docs/guides/MRI_GUIDE.md", #{title => "MRI (Resource Identifiers)"}},
        {"docs/guides/DEVELOPMENT.md", #{title => "Development Guide"}},
        {"docs/migrations/V1_TO_V2_PUBSUB.md", #{title => <<"Migration: V1 → V2 Pub/Sub"/utf8>>}},
        {"docs/ROADMAP.md", #{title => "Roadmap"}}
    ]},
    {main, "readme"},
    {source_url, "https://codeberg.org/macula-io/macula"},
    {assets, #{"assets" => "assets"}},
    {logo, "artwork/logo.svg"},
    {prefix_ref_vsn_with_v, false}
]}.

%% Hex package configuration
{hex, [
    {doc, #{provider => ex_doc}},
    {licenses, ["Apache-2.0"]},
    {links, #{
        <<"GitHub">> => <<"https://codeberg.org/macula-io/macula">>,
        <<"Documentation">> => <<"https://hexdocs.pm/macula">>,
        <<"Changelog">> => <<"https://codeberg.org/macula-io/macula/blob/main/CHANGELOG.md">>
    }},
    {description, "Macula HTTP/3 Mesh SDK — connect to relay mesh, pub/sub, RPC, Erlang distribution over QUIC, identity (Ed25519/UCAN/DID), MRI resource identifiers"},
    {files, [
        "src",
        "include",
        "priv",
        "native/macula_quic/Cargo.toml",
        "native/macula_quic/Cargo.lock",
        "native/macula_quic/src",
        "native/macula_crypto_nif/Cargo.toml",
        "native/macula_crypto_nif/Cargo.lock",
        "native/macula_crypto_nif/src",
        "native/macula_ucan_nif/Cargo.toml",
        "native/macula_ucan_nif/Cargo.lock",
        "native/macula_ucan_nif/src",
        "native/macula_did_nif/Cargo.toml",
        "native/macula_did_nif/Cargo.lock",
        "native/macula_did_nif/src",
        "native/macula_mri_nif/Cargo.toml",
        "native/macula_mri_nif/Cargo.lock",
        "native/macula_mri_nif/src",
        "rebar.config",
        "README.md",
        "CHANGELOG.md",
        "LICENSE",
        "CONTRIBUTING.md",
        "CODE_OF_CONDUCT.md",
        "assets",
        "artwork",
        "docs"
    ]}
]}.
