//
//  NSString+EZExtension.m
//  EZOpenSDKDemo
//
//  Created by JuneCheng on 2021/10/19.
//  Copyright © 2021 hikvision. All rights reserved.
//

#import "NSString+EZExtension.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>

#define iOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0)

#define JavaNotFound -1

@implementation NSString (EZExtension)


+ (BOOL)isBlank:(NSString *)str {
    if (!str) {
        return YES;
    }
    if ([[str trim] isEqualToString:@""]) {
        return YES;
    }
    
    return NO;
}


- (NSString *)add:(NSString *)str {
    return [NSString stringWithFormat:@"%@%@",self,str];
}


- (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW {
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = font;
    CGSize maxSize = CGSizeMake(maxW, MAXFLOAT);
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}

- (CGSize)sizeWithFont:(UIFont *)font maxH:(CGFloat)maxH {
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = font;
    CGSize maxSize = CGSizeMake(MAXFLOAT, maxH);
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}

- (CGSize)sizeWithFont:(UIFont *)font {
    return [self sizeWithFont:font maxW:MAXFLOAT];
}


- (NSString *)toStringBylength:(NSUInteger)length andReplace:(NSString *)str {
    NSString *strTemp = self;
    while (strTemp.length < length) {
        strTemp = [NSString stringWithFormat:@"%@%@",str,strTemp];
    }
    return strTemp;
}


- (NSString *)replaceStrWith:(NSString *)replaceStr afater:(NSString *)str between:(NSString *)start and:(NSString *)end {
    
    if (self == nil) {
        return self;
    }
    
    if (replaceStr == nil||str == nil||start == nil||end == nil) {
        return self;
    }
    
    //str在字符串里是否存在和位置
    NSUInteger length = [self length];
    NSRange range = [self rangeOfString:str];
    if (range.location>length) {
        return self;
    }
    
    //如果存在str则查询start的位置以及是否存在
    NSUInteger rangelocation =range.location+range.length;
    NSUInteger rangeLength =length-range.location-range.length;
    NSRange rangeStart =[self rangeOfString:start options:NSCaseInsensitiveSearch range:NSMakeRange(rangelocation,rangeLength)];
    if (rangeStart.location>length) {
        return self;
    }
    
    //查询end的情况
    rangelocation =rangeStart.location+rangeStart.length;
    rangeLength =length-rangeStart.location-rangeStart.length;
    
    NSRange rangeEnd =[self rangeOfString:end options:NSCaseInsensitiveSearch range:NSMakeRange(rangelocation,rangeLength)];
    if (rangeEnd.location>length) {
        return self;
    }
    //如果是连在一起的话则插入字符串
    if (rangeEnd.location-rangelocation==0) {
        NSMutableString *strTemp =[NSMutableString stringWithString:self];
        [strTemp insertString:replaceStr atIndex:rangelocation];
        return strTemp;
    }
    //没有连在一起的话则替换字符串
    NSRange rangeReplage = NSMakeRange(rangelocation, rangeEnd.location-rangelocation);
    
    return [self stringByReplacingCharactersInRange:rangeReplage withString:replaceStr];
}


- (NSString *)substringBeforeLast:(NSString *)str {
    NSInteger index = [self lastIndexOfStr:str];
    if (index == -1) {
        return  self;
    }
    return [self substringToIndex:index];
}


- (NSString *)substringBeforeFirst:(NSString *)str {
    NSInteger index = [self indexOfStr:str];
    if (index == -1) {
        return  self;
    }
    return [self substringToIndex:index];
}

- (NSString *)substringAfterLast:(NSString *)str {
    NSInteger index =[self lastIndexOfStr:str];
    if (index == -1) {
        return  self;
    }
    index = index+str.length;
    return [self substringFromIndex:(int)index toIndex:(int)self.length];
}




- (NSInteger)lastIndexOfStr:(NSString *)str {
    NSUInteger length = [self length];
    NSRange range = [self rangeOfString:str];
    NSInteger index = -1;
    if (range.location<length) {
        index = range.location;
    }
    while (range.location < length) {
        range = [self rangeOfString:str options:NSCaseInsensitiveSearch range:NSMakeRange(range.location+range.length,length-range.location-range.length)];
        if (range.location<length) {
            index = range.location;
        }
    }
    return index;
}

- (NSInteger)indexOfStr:(NSString *)str {
    NSUInteger length = [self length];
    NSRange range = [self rangeOfString:str];
    NSInteger index = -1;
    if (range.location<length) {
        index = range.location;
    }
    return index;
}

- (NSRange)getRangeWithStart:(NSString *)start andEnd:(NSString *)end {
    NSUInteger length = [self length];
    
    NSRange startRange = [self rangeOfString:start];
    if (startRange.location>length) {
        return  startRange;
    }
    NSUInteger rangelocation =startRange.location+startRange.length;
    NSUInteger rangeLength =length-startRange.location-startRange.length;
    
    NSRange endRange =[self rangeOfString:end options:NSCaseInsensitiveSearch range:NSMakeRange(rangelocation,rangeLength)];
    if (endRange.location>length) {
        return  endRange;
    }
    NSRange range = NSMakeRange(startRange.location, endRange.location-startRange.location+endRange.length);
    return range;
}

- (NSString *)getStrWithStart:(NSString *)start andEnd:(NSString *)end {
    NSRange range = [self getRangeWithStart:start andEnd:end];
    return [self substringWithRange:range];
}

- (NSString *)getStrBetween:(NSString *)start andEnd:(NSString *)end {
    NSString *strTemp =[self substringAfterLast:start];
    strTemp = [strTemp substringBeforeLast:end];
    return strTemp;
}



/**  Java-like method. Returns the char value at the specified index. */
- (unichar)charAt:(int)index {
    return [self characterAtIndex:index];
}

/**
 * Java-like method. Compares two strings lexicographically.
 * the value 0 if the argument string is equal to this string;
 * a value less than 0 if this string is lexicographically less than the string argument;
 * and a value greater than 0 if this string is lexicographically greater than the string argument.
 */
- (int)compareTo:(NSString *)anotherString {
    return [self compare:anotherString];
}

/** Java-like method. Compares two strings lexicographically, ignoring case differences. */
- (int)compareToIgnoreCase:(NSString *)str {
    return [self compare:str options:NSCaseInsensitiveSearch];
}

/** Java-like method. Returns true if and only if this string contains the specified sequence of char values. */
- (BOOL)isContainChinese {
    NSUInteger length = [self length];
    for (NSUInteger i = 0; i < length; i++) {
        NSRange range = NSMakeRange(i, 1);
        NSString *subString = [self substringWithRange:range];
        const char *cString = [subString UTF8String];
        if (strlen(cString) == 3) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)contains:(NSString *)str {
    NSRange range = [self rangeOfString:str];
    return (range.location != NSNotFound);
}

- (BOOL)startsWith:(NSString *)prefix {
    return [self hasPrefix:prefix];
}

- (BOOL)endsWith:(NSString *)suffix {
    return [self hasSuffix:suffix];
}

- (BOOL)equals:(NSString *)anotherString {
    return [self isEqualToString:anotherString];
}

- (BOOL)equalsIgnoreCase:(NSString *)anotherString {
    return [[self toLowerCase] equals:[anotherString toLowerCase]];
}

- (int)indexOfChar:(unichar)ch {
    return [self indexOfChar:ch fromIndex:0];
}

- (int)indexOfChar:(unichar)ch fromIndex:(int)index {
    NSUInteger len = self.length;
    for (int i = index; i < len; ++i) {
        if (ch == [self charAt:i]) {
            return i;
        }
    }
    return JavaNotFound;
}

- (int)indexOfString:(NSString *)str {
    NSRange range = [self rangeOfString:str];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return (int)range.location;
}

- (int)indexOfString:(NSString *)str fromIndex:(int)index {
    NSRange fromRange = NSMakeRange(index, self.length - index);
    NSRange range = [self rangeOfString:str options:NSLiteralSearch range:fromRange];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return (int)range.location;
}

- (int)lastIndexOfChar:(unichar)ch {
    int len = (int)self.length;
    for (int i = len-1; i >=0; --i) {
        if ([self charAt:i] == ch) {
            return i;
        }
    }
    return JavaNotFound;
}

- (int)lastIndexOfChar:(unichar)ch fromIndex:(int)index {
    int len = (int)self.length;
    if (index >= len) {
        index = len - 1;
    }
    for (int i = index; i >= 0; --i) {
        if ([self charAt:i] == ch) {
            return index;
        }
    }
    return JavaNotFound;
}

- (int)lastIndexOfString:(NSString *)str {
    NSRange range = [self rangeOfString:str options:NSBackwardsSearch];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return (int)range.location;
}

- (int)lastIndexOfString:(NSString *)str fromIndex:(int)index {
    NSRange fromRange = NSMakeRange(0, index);
    NSRange range = [self rangeOfString:str options:NSBackwardsSearch range:fromRange];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return (int)range.location;
}

- (NSString *)substringFromIndex:(int)beginIndex toIndex:(int)endIndex {
    if (endIndex <= beginIndex) {
        return @"";
    }
    NSRange range = NSMakeRange(beginIndex, endIndex - beginIndex);
    return [self substringWithRange:range];
}

- (NSString *)toLowerCase {
    return [self lowercaseString];
}

- (NSString *)toUpperCase {
    return [self uppercaseString];
}

- (NSString *)trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)replaceAll:(NSString *)origin with:(NSString *)replacement {
    return [self stringByReplacingOccurrencesOfString:origin withString:replacement];
}

- (NSArray *)split:(NSString *)separator {
    return [self componentsSeparatedByString:separator];
}

- (NSString *)urlEncode {
    NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]";
    NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
    return [[self description] stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}

- (NSString *)urlDecode {
    
    return [self stringByRemovingPercentEncoding];
}


// calculates the MD5 hash of a key
- (NSString *)md5StringForString {
    const char *str = [self UTF8String];
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (uint32_t)strlen(str), r);
    return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
}

- (NSString *)getMd5_32Bit {
    const char *string = self.UTF8String;
    int length = (int)strlen(string);
    unsigned char bytes[CC_MD5_DIGEST_LENGTH];
    CC_MD5(string, length, bytes);
    return [self stringFromBytes:bytes length:CC_MD5_DIGEST_LENGTH];
}



- (BOOL)isIdentityNum {
    
    NSString *identityExpression = @"(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])";
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", identityExpression];
    
    return [regextestmobile evaluateWithObject:self];
}


- (NSString *)stringFromBytes:(unsigned char *)bytes length:(int)length {
    NSMutableString *mutableString = @"".mutableCopy;
    for (int i = 0; i < length; i++)
        [mutableString appendFormat:@"%02x", bytes[i]];
    return [NSString stringWithString:mutableString];
}


- (NSString *)deleteFanXieGang {
    NSMutableString *responseString = [NSMutableString stringWithString:self];
    NSString *character = nil;
    for (int i = 0; i < responseString.length; i ++) {
        
        character = [responseString substringWithRange:NSMakeRange(i, 1)];
        if ([character isEqualToString:@"\""])
            [responseString deleteCharactersInRange:NSMakeRange(i, 1)];
    }
    return responseString;
    
}

- (NSDictionary *) dictionaryWithJsonString {
    if (self == nil) {
        return nil;
    }
    NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err) {
        NSLog(@"json解析失败：%@",err);
        return nil;
    }
    return dic;
}

// 移除转义字符
- (NSString *)removeEscapeChar {
    NSMutableString *responseString = [NSMutableString stringWithString:self];
    NSString *character = nil;
    for (int i = 0; i < responseString.length; i ++) {
        character = [responseString substringWithRange:NSMakeRange(i, 1)];
        if ([character isEqualToString:@"\\"])
            [responseString deleteCharactersInRange:NSMakeRange(i, 1)];
    }
    return [NSString stringWithFormat:@"%@",responseString];
}

//正则去除网络标签
- (NSString *)removeHTMLTags {
    NSString *string = self;
    NSRegularExpression *regularExpretion=[NSRegularExpression regularExpressionWithPattern:@"<[^>]*>|\n|&nbsp;"
                                                                                    options:0
                                                                                      error:nil];
    string=[regularExpretion stringByReplacingMatchesInString:string options:NSMatchingReportProgress range:NSMakeRange(0, string.length) withTemplate:@""];
    return string;
}

// 字符串进行UTF-8编码
- (NSString *)encodeUTF8 {
    NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]";
    NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
    return [[self description] stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}

+ (NSString *)getUUIDString {
    // Create universally unique identifier (object)
    CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault);
    // Get the string representation of CFUUID object.
    NSString *uuidStr = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuidObject));
    CFRelease(uuidObject);
    
    return uuidStr;
}

- (NSString *)addXMLStatementHead {
    return [NSString stringWithFormat:@"%@%@",@"<?xml version=\"1.0\" encoding=\"utf-8\"?>",self];
}

- (BOOL)isEqualToAnyStringInArray:(NSArray *)array {
    for (NSString *value in array) {
        NSString *string = [NSString stringWithFormat:@"%@", value];
        if ([string isEqualToString:self]) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)isContainsAnyStringInArray:(NSArray *)array {
    for (NSString *value in array) {
        NSString *string = [NSString stringWithFormat:@"%@", value];
        if ([self containsString:string]) {
            return YES;
        }
    }
    return NO;
}

- (BOOL)isRegularUrl {
    NSString *pattern = @"\\b(([\\w-]+://?|www[.])[^\\s()<>]+(?:\\([\\w\\d]+\\)|([^[:punct:]\\s]|/)))";
    NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];
    NSArray *results = [regex matchesInString:self options:0 range:NSMakeRange(0, self.length)];
    return results.count > 0;
}

- (BOOL)isNumberString {
    NSScanner *scan = [NSScanner scannerWithString:self];
    int val;
    return [scan scanInt:&val] && [scan isAtEnd];
}

- (NSData *)convertHexStringToData {
    if (!self || [self length] == 0) {
        return nil;
    }
        
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([self length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [self length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [self substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}

- (NSString *)getNumberFromString {
    NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    return [[self componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
}

- (NSMutableAttributedString *)stressWithKeywords:(NSArray<NSString *> *)keywords {
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self];
    [keywords enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        // 获取range
        NSMutableArray *ranges = [self rangesOfKeyword:obj];
        for (int i = 0; i < ranges.count; i ++) {
            NSRange range = NSMakeRange([ranges[i] intValue], obj.length);
            // 设置样式
            [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
            [attrString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:18.f] range:range];
        }
    }];
    return attrString;
}

- (NSMutableArray *)rangesOfKeyword:(NSString *)keyword {
    NSMutableArray *rangeArray = [NSMutableArray array];
    
    if (keyword == nil && [keyword isEqualToString:@""]) {
        return nil;
    }
    NSRange rang = [self rangeOfString:keyword]; //获取第一次出现的range
    
    if (rang.location != NSNotFound && rang.length != 0) {
        [rangeArray addObject:[NSNumber numberWithInteger:rang.location]];//将第一次的加入到数组中
        NSRange rang1 = {0, 0};
        NSInteger location = 0;
        NSInteger length = 0;
        for (int i = 0;; i++) {
            if (0 == i) {
               //去掉这个abc字符串
                location = rang.location + rang.length;
                length = self.length - rang.location - rang.length;
                rang1 = NSMakeRange(location, length);
            } else {
                location = rang1.location + rang1.length;
                length = self.length - rang1.location - rang1.length;
                rang1 = NSMakeRange(location, length);
            }
            //在一个range范围内查找另一个字符串的range
            rang1 = [self rangeOfString:keyword options:NSCaseInsensitiveSearch range:rang1];
            if (rang1.location == NSNotFound && rang1.length == 0) {
                break;
            } else {//添加符合条件的location进数组
                [rangeArray addObject:[NSNumber numberWithInteger:rang1.location]];
            }
        }
        return rangeArray;
    }
    return nil;
}

@end
