//
//  PhobosSendManager.m
//  GMPhobos
//
//  Created by Locus on 2020/3/3.
//

#import "PhobosSendManager.h"
#import <GMCache/GMCache.h>
#import <MJExtension/MJExtension.h>
#import "PhobosConfig.h"
#import "Phobos.h"
#import "PhobosUtil.h"

#ifdef APPSTORE
#define GMExactExposureApi @"https://log.igengmei.com/log/precise_exposure"
#else
#define GMExactExposureApi @"http://log.test.igengmei.com/log/precise_exposure"
#endif

@implementation PhobosSendManager

+ (void)initialize {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 处理非灰情况下未发送完成数据
        [self disposeOldData];
    });
}

// TODO: 全量以后，一定时间需要清除下面逻辑
+ (void)disposeOldData {
    NSMutableArray *total = [NSMutableArray new];
    NSArray *normalDataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey];
    NSArray *immiDataArray = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    [total addObjectsFromArray:normalDataArray];
    [total addObjectsFromArray:immiDataArray];
    if (total.count > 0) {
        /** 获取非灰度下所有普通埋点，进行发送 */
        [self sendDataArray:total currentAPI:Phobos.sharedClient.serverAPI success:^(NSInteger code) {
            if (code == 200) {
                [GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
                [GMCache removeObjectAtDocumentPathWithkey:PhobosTempCacheKey];
            }
        }];
    }
    NSString *exposureAPI = GMExactExposureApi;
    NSArray *exposureArray = [GMCache fetchObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
    if (exposureArray.count > 0) {
        /** 获取非灰度下发送失败的埋点，进行发送 */
        [self sendDataArray:exposureArray currentAPI:exposureAPI success:^(NSInteger code) {
            if (code = 200) {
                [GMCache removeObjectAtDocumentPathWithkey:[PhobosUtil MD5String:exposureAPI]];
            }
        }];
    }
}

+ (void)sendDataWithEntities:(NSArray<PhobosSendDataEntity *> *)sendDataEntities completion:(void (^)(NSArray<PhobosSendDataEntity *> * _Nonnull, NSInteger))completion {
    if (sendDataEntities.count == 0) {
        return;
    } else if (sendDataEntities.count > PhobosMaxSendCount) {
        /** 如果数据超过 PhobosMaxSendCount 数据规模，进行拆分，分批发送，默认100条 */
        NSMutableArray *temp = [NSMutableArray arrayWithCapacity:PhobosMaxSendCount];
        [sendDataEntities enumerateObjectsUsingBlock:^(PhobosSendDataEntity * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (temp.count >= PhobosMaxSendCount) {
                // 会调用当前方法，但数据规模不会满足 > PhobosMaxSendCount，不会让数据走到下面的发送，拆分完成 会执行return
                [self sendDataWithEntities:temp completion:completion];
                [temp removeAllObjects];
            }
            [temp addObject:obj];
        }];
        return;
    }
    NSMutableDictionary *sendDataMap = [NSMutableDictionary new];
    // 将相同api的数据合并
    [sendDataEntities enumerateObjectsUsingBlock:^(PhobosSendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSMutableArray *sendData = sendDataMap[obj.api] ?: [NSMutableArray new];
        [sendData addObject:obj];
        [sendDataMap setValue:sendData forKey:obj.api];
    }];
    
    // 将实体转为待发送数据，取出PhobosSendDataEntity中的data，并发送
    [sendDataMap enumerateKeysAndObjectsUsingBlock:^(NSString *api, NSArray<PhobosSendDataEntity *> *entities, BOOL * _Nonnull stop) {
        NSMutableArray *sendDatas = [NSMutableArray new];
        [entities enumerateObjectsUsingBlock:^(PhobosSendDataEntity *obj, NSUInteger idx, BOOL * _Nonnull stop) {
            id data = [obj.data mj_JSONObject];
            if (data) {
                [sendDatas addObject:data];
            }
        }];
        
        if (sendDatas.count > 0) {
            [self sendDataArray:sendDatas currentAPI:api success:^(NSInteger code) {
                if (completion) {
                    completion(entities, code);
                }
            }];
        }
    }];
}

+ (void)sendDataArray:(NSArray *)dataArray currentAPI:(NSString *)currentAPI success:(SendDataSuccessBlock)success {
    NSData *JSON = [PhobosUtil encodeJSON:dataArray];
    NSData *compressedData = [PhobosUtil compressData:JSON];
    [PhobosUtil sendData:compressedData currentAPI:currentAPI success:^(NSInteger code) {
        if (success) {
            success(code);
        }
    }];
}

@end
