//
// Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

#import "FunctionalUtil.h"

NS_ASSUME_NONNULL_BEGIN

@interface FUBadArgument : NSException

+ (FUBadArgument *)new:(NSString *)reason;
+ (void)raise:(NSString *)message;

@end

@implementation FUBadArgument

+ (FUBadArgument *)new:(NSString *)reason
{
    return [[FUBadArgument alloc] initWithName:@"Invalid Argument" reason:reason userInfo:nil];
}
+ (void)raise:(NSString *)message
{
    [FUBadArgument raise:@"Invalid Argument" format:@"%@", message];
}

@end

#define tskit_require(expr)                                                                                            \
    if (!(expr)) {                                                                                                     \
        NSString *reason =                                                                                             \
            [NSString stringWithFormat:@"require %@ (in %s at line %d)", (@ #expr), __FILE__, __LINE__];               \
        OWSLogError(@"%@", reason);                                                                                    \
        [FUBadArgument raise:reason];                                                                                  \
    };


@implementation NSArray (FunctionalUtil)

- (NSArray *)map:(id (^)(id item))projection
{
    tskit_require(projection != nil);

    NSMutableArray *r = [NSMutableArray arrayWithCapacity:self.count];
    for (id e in self) {
        [r addObject:projection(e)];
    }
    return r;
}

- (NSArray *)filter:(BOOL (^)(id item))predicate
{
    tskit_require(predicate != nil);

    NSMutableArray *r = [NSMutableArray array];
    for (id e in self) {
        if (predicate(e)) {
            [r addObject:e];
        }
    }
    return r;
}

@end

NS_ASSUME_NONNULL_END
