// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../../application_layer.dart';

/// Result wrapper for expected application success/failure paths.
class ApplicationResult<T> {
  /// Creates a `ApplicationResult._` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  const ApplicationResult._({
    this.value,
    this.failure,
  });

  /// Successful result carrying [value].
  factory ApplicationResult.success(T value) {
    return ApplicationResult._(value: value);
  }

  /// Expected failure result.
  factory ApplicationResult.failure(ApplicationFailure failure) {
    return ApplicationResult._(failure: failure);
  }

  /// Successful value, if any.
  final T? value;

  /// Typed failure, if the operation did not succeed.
  final ApplicationFailure? failure;

  /// Whether the operation succeeded.
  bool get isSuccess => failure == null;

  /// Whether the operation failed with a typed application failure.
  bool get isFailure => failure != null;

  /// Return the value or throw if this result is a failure.
  T get requireValue {
    if (failure != null) {
      throw StateError(
          'Application result is a failure: ${failure!.code.name}');
    }
    return value as T;
  }
}
