/* Copyright Airship and Contributors */

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class UAJSONValueMatcher;

/**
 * Represents the possible error conditions when deserializing matcher from JSON.
 */
typedef NS_ENUM(NSInteger, UAJSONMatcherErrorCode) {
    /**
     * Indicates an error with the matcher JSON definition.
     */
    UAJSONMatcherErrorCodeInvalidJSON,
};

/**
 * The domain for NSErrors generated by `matcherWithJSON:error:`.
 */
extern NSString * const UAJSONMatcherErrorDomain;

/**
 * Matcher for a JSON payload.
 */
@interface UAJSONMatcher : NSObject

///---------------------------------------------------------------------------------------
/// @name JSON Matcher Properties
///---------------------------------------------------------------------------------------

/**
 * The matcher's JSON payload.
 */
@property(nonatomic, readonly) NSDictionary *payload;

///---------------------------------------------------------------------------------------
/// @name JSON Matcher Factories
///---------------------------------------------------------------------------------------

/**
 * Factory method to create a JSON matcher.
 *
 * @param valueMatcher Matcher to apply to the value.
 * @return A JSON matcher.
 */
+ (instancetype)matcherWithValueMatcher:(UAJSONValueMatcher *)valueMatcher;

/**
 * Factory method to create a JSON matcher.
 *
 * @param valueMatcher Matcher to apply to the value.
 * @param scope Used to path into the object before evaluating the value.
 * @return A JSON matcher.
 */
+ (instancetype)matcherWithValueMatcher:(UAJSONValueMatcher *)valueMatcher scope:(NSArray<NSString *>*)scope;

/**
 * Factory method to create a matcher from a JSON payload.
 *
 * @param json The JSON payload.
 * @param error An NSError pointer for storing errors, if applicable.
 * @return A value matcher, or `nil` if the JSON is invalid.
 */
+ (nullable instancetype)matcherWithJSON:(id)json error:( NSError * _Nullable *)error;

///---------------------------------------------------------------------------------------
/// @name JSON Matcher Evaluation
///---------------------------------------------------------------------------------------

/**
 * Evaluates the object with the matcher.
 *
 * @param object The object to evaluate.
 * @return `YES` if the matcher matches the object, otherwise `NO`.
 */
- (BOOL)evaluateObject:(nullable id)object;



@end

NS_ASSUME_NONNULL_END
