//
//  ZYJQNUploadInfoCollector.h
//  ZYJQiniuSDK
//
//  Created by WorkSpace_Sun on 2020/4/15.
//  Copyright © 2020 Qiniu. All rights reserved.
//

#import <Foundation/Foundation.h>

#define Collector [ZYJQNUploadInfoCollector sharedInstance]

@class ZYJQNHttpResponseInfo;
@class ZYJQNResponseInfo;

// request types
typedef enum : NSUInteger {
    ZYJQNRequestType_form,
    ZYJQNRequestType_mkblk,
    ZYJQNRequestType_bput,
    ZYJQNRequestType_mkfile,
    ZYJQNRequestType_put,
    ZYJQNRequestType_initParts,
    ZYJQNRequestType_uploadParts,
    ZYJQNRequestType_completeParts,
    ZYJQNRequestType_ucQuery,
    ZYJQNRequestType_httpdnsQuery
} ZYJQNRequestType;

typedef NSString ZYJQNCollectKey;

// update key
extern ZYJQNCollectKey *const ZYJCK_bucket;
extern ZYJQNCollectKey *const ZYJCK_key;
extern ZYJQNCollectKey *const ZYJCK_targetRegionId;
extern ZYJQNCollectKey *const ZYJCK_currentRegionId;
extern ZYJQNCollectKey *const ZYJCK_result;
extern ZYJQNCollectKey *const ZYJCK_recoveredFrom;
extern ZYJQNCollectKey *const ZYJCK_fileSize;
extern ZYJQNCollectKey *const ZYJCK_blockApiVersion;

// append key
extern ZYJQNCollectKey *const ZYJCK_blockBytesSent;
extern ZYJQNCollectKey *const ZYJCK_totalBytesSent;

// Upload Result Type
extern NSString *const ZYJupload_ok;   // 上传成功
extern NSString *const ZYJzero_size_file;  // ⽂件⼤小错误
extern NSString *const ZYJinvalid_file;  // 文件内容错误
extern NSString *const ZYJinvalid_args; // 调用参数出错
extern NSString *const ZYJlocal_io_error; // 本地 I/O 错误

/// Network Error Type
extern NSString *const ZYJunknown_error;   // 未知错误
extern NSString *const ZYJnetwork_error; // 未知网络错误
extern NSString *const ZYJnetwork_timeout;   // 超时错误
extern NSString *const ZYJunknown_host;    // DNS 解析错误
extern NSString *const ZYJcannot_connect_to_host;  // 连接服务器器错误
extern NSString *const ZYJtransmission_error;  // 传输错误
extern NSString *const ZYJproxy_error;     // 使用了 HTTP Proxy 且 Proxy 出错
extern NSString *const ZYJssl_error;    // SSL 加密错误
extern NSString *const ZYJresponse_error;  // 收到响应，但状态码非 200
extern NSString *const ZYJparse_error;  // 解析响应错误
extern NSString *const ZYJmalicious_response;   // 用户劫持错误
extern NSString *const ZYJuser_canceled;   // 用户主动取消
extern NSString *const ZYJbad_request;   // API 失败是由于客户端的参数错误导致，⽆法依靠重试来解决的(例如 4xx 错误， upload token 错误，⽬标 bucket 不存在，⽂件已经存在，区域不正确，额度不够 等)
extern NSString *const ZYJprotocol_error;   // 协议错误

extern int64_t ZYJQN_IntNotSet;

// 用于统计上传质量 和生成ZYJQNResponseInfo实例
@interface ZYJQNUploadInfoCollector : NSObject

- (id)init __attribute__((unavailable("Use sharedInstance: instead.")));
+ (instancetype)sharedInstance;

/**
 *   注册上传统计实例
 *
 *   @param identifier  此次上传的唯一标识
 *   @param token       上传token
 *
 */
- (void)registerWithIdentifier:(NSString *)identifier token:(NSString *)token;

/**
*   更新ZYJQNCollectKey对应的上传信息
*
*   @param key              需要更新的ZYJQNCollectKey
*   @param identifier       此次上传的唯一标识
*
*/
- (void)update:(ZYJQNCollectKey *)key value:(id)value identifier:(NSString *)identifier;

/**
*   拼接ZYJQNCollectKey对应的上传信息   一般用于拼接数字类型常量
*
*   @param key              需要拼接的ZYJQNCollectKey
*   @param identifier       此次上传的唯一标识
*
*/
- (void)append:(ZYJQNCollectKey *)key value:(id)value identifier:(NSString *)identifier;

/**
*   记录此次上传中单次http请求结果
*
*   @param upType                 请求类型
*   @param httpResponseInfo   请求返回信息
*   @param fileOffset              data偏移量（非分片上传请求时该值为0）
*   @param targetRegionId       目标区域id
*   @param currentRegionId     当前区域id
*   @param identifier              此次上传的唯一标识
*
*/
- (void)addRequestWithType:(ZYJQNRequestType)upType httpResponseInfo:(ZYJQNHttpResponseInfo *)httpResponseInfo fileOffset:(int64_t)fileOffset targetRegionId:(NSString *)targetRegionId currentRegionId:(NSString *)currentRegionId identifier:(NSString *)identifier;

/**
*   根据http请求结果返回ZYJQNResponseInfo
*
*   @param lastHttpResponseInfo    最后一个请求的返回信息
*   @param identifier                    此次上传的唯一标识
*
*   @return ZYJQNResponseInfo          返回信息
*/
- (ZYJQNResponseInfo *)completeWithHttpResponseInfo:(ZYJQNHttpResponseInfo *)lastHttpResponseInfo identifier:(NSString *)identifier;

/**
*   参数问题导致上传结束并返回ZYJQNResponseInfo
*
*   @param text                     描述
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)completeWithInvalidArgument:(NSString *)text identifier:(NSString *)identifier;

/**
*   token无效导致上传结束并返回ZYJQNResponseInfo
*
*   @param text                     描述
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)completeWithInvalidToken:(NSString *)text identifier:(NSString *)identifier;

/**
*   文件内容出错导致上传结束并返回ZYJQNResponseInfo
*
*   @param error                    报错信息
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)completeWithFileError:(NSError *)error identifier:(NSString *)identifier;

/**
*   本地 I/O 出错导致上传结束并返回ZYJQNResponseInfo
*
*   @param error                    报错信息
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)completeWithLocalIOError:(NSError *)error identifier:(NSString *)identifier;

/**
*   zero data问题导致上传结束并返回ZYJQNResponseInfo
*
*   @param path                     文件路径
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)completeWithZeroData:(NSString *)path identifier:(NSString *)identifier;

/**
*   用户取消导致上传结束并返回ZYJQNResponseInfo
*
*   @param identifier               此次上传的唯一标识
*
*   @return ZYJQNResponseInfo     返回信息
*/
- (ZYJQNResponseInfo *)userCancel:(NSString *)identifier;

@end
