//
//  ZYJQNZoneInfo.m
//  ZYJQiniuSDK
//
//  Created by yangsen on 2020/4/16.
//  Copyright © 2020 Qiniu. All rights reserved.
//

#import "ZYJQNZoneInfo.h"

static NSString *const zoneNames[] = {@"z0", @"z1", @"z2", @"as0", @"na0", @"unknown"};

@interface ZYJQNZoneInfo()

@property (nonatomic, assign) ZYJQNZoneInfoType type;
@property (nonatomic, assign) ZYJQNZoneRegion zoneRegion;
@property (nonatomic, assign) long ttl;
@property (nonatomic, strong) NSDate *buildDate;
@property (nonatomic, strong) NSMutableArray<NSString *> *upDomainsList;
@property (nonatomic, strong) NSMutableDictionary *upDomainsDic;

@end
@implementation ZYJQNZoneInfo

- (instancetype)init:(long)ttl
       upDomainsList:(NSMutableArray<NSString *> *)upDomainsList
        upDomainsDic:(NSMutableDictionary *)upDomainsDic
        zoneRegion:(ZYJQNZoneRegion)zoneRegion {
    if (self = [super init]) {
        _ttl = ttl;
        _buildDate = [NSDate date];
        _upDomainsList = upDomainsList;
        _upDomainsDic = upDomainsDic;
        _zoneRegion = zoneRegion;
        _type = ZYJQNZoneInfoTypeMain;
    }
    return self;
}

- (ZYJQNZoneInfo *)buildInfoFromJson:(NSDictionary *)resp {
    long ttl = [[resp objectForKey:@"ttl"] longValue];
    NSDictionary *up = [resp objectForKey:@"up"];
    NSDictionary *acc = [up objectForKey:@"acc"];
    NSDictionary *src = [up objectForKey:@"src"];
    NSDictionary *old_acc = [up objectForKey:@"old_acc"];
    NSDictionary *old_src = [up objectForKey:@"old_src"];
    NSArray *urlDicList = [[NSArray alloc] initWithObjects:acc, src, old_acc, old_src, nil];
    NSMutableArray *domainList = [[NSMutableArray alloc] init];
    NSMutableDictionary *domainDic = [[NSMutableDictionary alloc] init];
    //main
    for (int i = 0; i < urlDicList.count; i++) {
        if ([[urlDicList[i] allKeys] containsObject:@"main"]) {
            NSArray *mainDomainList = urlDicList[i][@"main"];
            for (int i = 0; i < mainDomainList.count; i++) {
                [domainList addObject:mainDomainList[i]];
                [domainDic setObject:[NSDate dateWithTimeIntervalSince1970:0] forKey:mainDomainList[i]];
            }
        }
    }
    
    //backup
    for (int i = 0; i < urlDicList.count; i++) {
        if ([[urlDicList[i] allKeys] containsObject:@"backup"]) {
            NSArray *mainDomainList = urlDicList[i][@"backup"];
            for (int i = 0; i < mainDomainList.count; i++) {
                [domainList addObject:mainDomainList[i]];
                [domainDic setObject:[NSDate dateWithTimeIntervalSince1970:0] forKey:mainDomainList[i]];
            }
        }
    }
    
    // judge zone region via io
    NSDictionary *io = [resp objectForKey:@"io"];
    NSDictionary *io_src = [io objectForKey:@"src"];
    NSArray *io_main = [io_src objectForKey:@"main"];
    NSString *io_host = io_main.count > 0 ? io_main[0] : nil;
    
    ZYJQNZoneRegion zoneRegion = ZYJQNZoneRegion_unknown;
    if ([io_host isEqualToString:@"iovip.qbox.me"]) {
        zoneRegion = ZYJQNZoneRegion_z0;
    } else if ([io_host isEqualToString:@"iovip-z1.qbox.me"]) {
        zoneRegion = ZYJQNZoneRegion_z1;
    } else if ([io_host isEqualToString:@"iovip-z2.qbox.me"]) {
        zoneRegion = ZYJQNZoneRegion_z2;
    } else if ([io_host isEqualToString:@"iovip-na0.qbox.me"]) {
        zoneRegion = ZYJQNZoneRegion_na0;
    } else if ([io_host isEqualToString:@"iovip-as0.qbox.me"]) {
        zoneRegion = ZYJQNZoneRegion_as0;
    } else {
        zoneRegion = ZYJQNZoneRegion_unknown;
    }
    
    return [[ZYJQNZoneInfo alloc] init:ttl upDomainsList:domainList upDomainsDic:domainDic zoneRegion:zoneRegion];
}

- (void)frozenDomain:(NSString *)domain {
    NSTimeInterval secondsFor10min = 10 * 60;
    NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:secondsFor10min];
    [self.upDomainsDic setObject:tomorrow forKey:domain];
}

- (BOOL)isValid{
    NSDate *currentDate = [NSDate date];
    if (self.ttl > [currentDate timeIntervalSinceDate:self.buildDate]) {
        return YES;
    } else {
        return NO;
    }
}

@end

@interface ZYJQNZonesInfo()
@end
@implementation ZYJQNZonesInfo

- (instancetype)initWithZonesInfo:(NSArray<ZYJQNZoneInfo *> *)zonesInfo{
    self = [super init];
    if (self) {
        _zonesInfo = zonesInfo;
    }
    return self;
}

+ (instancetype)buildZonesInfoWithResp:(NSDictionary *)resp {
    
    NSMutableArray *zonesInfo = [NSMutableArray array];
    NSArray *hosts = resp[@"hosts"];
    for (NSInteger i = 0; i < hosts.count; i++) {
        ZYJQNZoneInfo *zoneInfo = [[[ZYJQNZoneInfo alloc] init] buildInfoFromJson:hosts[i]];
        zoneInfo.type = i == 0 ? ZYJQNZoneInfoTypeMain : ZYJQNZoneInfoTypeBackup;
        [zonesInfo addObject:zoneInfo];
    }
    return [[[self class] alloc] initWithZonesInfo:zonesInfo];
}

- (ZYJQNZoneInfo *)getZoneInfoWithType:(ZYJQNZoneInfoType)type {
    
    ZYJQNZoneInfo *zoneInfo = nil;
    for (ZYJQNZoneInfo *info in _zonesInfo) {
        if (info.type == type) {
            zoneInfo = info;
            break;
        }
    }
    return zoneInfo;
}

- (NSString *)getZoneInfoRegionNameWithType:(ZYJQNZoneInfoType)type {
    
    ZYJQNZoneInfo *zoneInfo = [self getZoneInfoWithType:type];
    return zoneNames[zoneInfo.zoneRegion];
}

- (BOOL)hasBackupZone {
    return _zonesInfo.count > 1;
}

@end
