// Standalone tests for reasampler::mode_enable — no REAPER, no test framework. Asserts the
// opposite-mode tag-button enablement predicate for BOTH active modes (the acceptance criterion:
// covered for both, not only whichever a DAW pass sat in).
//
// The rule (L5 refinement 3): a tag button whose target is `t` is LIVE iff `t` != the active
// mode — you tag INTO the mode you are not currently in. When Design is active, "…: Arrange"
// buttons are live and "…: Design" buttons are dead; when Arrange is active, the reverse. An
// unrecognized active id fails OPEN (every button live) so a future mode never dead-locks the bar.

#include "../src/core/ui/mode_enable.h"
#include "../src/core/view/view_mode_model.h"  // kArrangeModeId / kDesignModeId — the ids the rule keys off

#include <cstdio>
#include <string>

using namespace reasampler;
using namespace reasampler::ui;

static int g_fail = 0;
#define CHECK(cond) do { if(!(cond)) { \
    std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)

// When ARRANGE is active: only the Design-target buttons are live (tag into Design); the
// Arrange-target buttons are dead (already in Arrange — nothing to do).
static void testArrangeActive() {
    const std::string active = kArrangeModeId;
    CHECK(!tagButtonEnabled(active, TagTarget::Arrange));  // dead — already active mode
    CHECK(tagButtonEnabled(active, TagTarget::Design));    // live — opposite mode
}

// When DESIGN is active: the reverse — only the Arrange-target buttons are live.
static void testDesignActive() {
    const std::string active = kDesignModeId;
    CHECK(tagButtonEnabled(active, TagTarget::Arrange));   // live — opposite mode
    CHECK(!tagButtonEnabled(active, TagTarget::Design));   // dead — already active mode
}

// Exactly one of the two targets is live in each mode (the buttons are complementary — a real
// pair, never both-live or both-dead). This is the invariant the disabled/enabled visuals rely on.
static void testExactlyOneTargetLivePerMode() {
    CHECK(tagButtonEnabled(kArrangeModeId, TagTarget::Arrange) !=
          tagButtonEnabled(kArrangeModeId, TagTarget::Design));
    CHECK(tagButtonEnabled(kDesignModeId, TagTarget::Arrange) !=
          tagButtonEnabled(kDesignModeId, TagTarget::Design));
}

// An unrecognized active id (neither seed mode — e.g. empty when no session, or a future mode)
// fails OPEN: every button live, so the user can always reach the action.
static void testUnknownActiveFailsOpen() {
    CHECK(tagButtonEnabled("", TagTarget::Arrange));
    CHECK(tagButtonEnabled("", TagTarget::Design));
    CHECK(tagButtonEnabled("some-future-mode", TagTarget::Arrange));
    CHECK(tagButtonEnabled("some-future-mode", TagTarget::Design));
}

int main() {
    testArrangeActive();
    testDesignActive();
    testExactlyOneTargetLivePerMode();
    testUnknownActiveFailsOpen();

    if (g_fail == 0) std::printf("mode_enable: all tests passed\n");
    else std::printf("mode_enable: %d CHECK(s) FAILED\n", g_fail);
    return g_fail == 0 ? 0 : 1;
}
