package de.effigenix.domain.inventory;

import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.junit.FuzzTest;
import de.effigenix.shared.common.Result;

/**
 * Fuzz test for the InventoryCount aggregate.
 *
 * Exercises create() with fuzzed drafts, then applies a random sequence of
 * addCountItem() operations. Verifies that no input combination causes an
 * unhandled exception – all invalid inputs must be caught and returned as
 * Result.Failure.
 *
 * Run: make fuzz  |  make fuzz/single TEST=InventoryCountFuzzTest
 */
class InventoryCountFuzzTest {

    @FuzzTest(maxDuration = "5m")
    void fuzzInventoryCount(FuzzedDataProvider data) {
        var draft = new InventoryCountDraft(
                data.consumeString(50),
                data.consumeString(30),
                data.consumeString(30)
        );

        switch (InventoryCount.create(draft)) {
            case Result.Failure(var err) -> { }
            case Result.Success(var count) -> {
                int ops = data.consumeInt(1, 20);
                for (int i = 0; i < ops; i++) {
                    var itemDraft = new CountItemDraft(
                            data.consumeString(50),
                            data.consumeString(30),
                            data.consumeString(20)
                    );
                    switch (count.addCountItem(itemDraft)) {
                        case Result.Failure(var err) -> { }
                        case Result.Success(var item) -> {
                            // Verify computed properties don't throw
                            item.deviation();
                            item.isCounted();
                            item.id();
                            item.articleId();
                            item.expectedQuantity();
                        }
                    }
                }
                // Exercise state transitions with fuzzed input
                switch (count.startCounting()) {
                    case Result.Failure(var err) -> { }
                    case Result.Success(var ignored) -> {
                        // Try to complete with fuzzed completedBy
                        switch (count.complete(data.consumeString(50))) {
                            case Result.Failure(var err2) -> { }
                            case Result.Success(var ignored2) -> { }
                        }
                    }
                }
                // Verify aggregate getters don't throw
                count.isActive();
                count.countItems();
                count.id();
                count.storageLocationId();
                count.countDate();
                count.status();
                count.initiatedBy();
                count.completedBy();
                count.createdAt();
            }
        }
    }
}
