//
//  TCGBError.h
//  Gamebase
//
//  Created by NHN on 2016. 6. 20..
//  © NHN Corp. All rights reserved.
//
#ifndef TCGBError_h
#define TCGBError_h

#import <Foundation/Foundation.h>
#import <Gamebase/TCGBConstants.h>

NS_ASSUME_NONNULL_BEGIN

extern NSString* const kTCGBDomainGamebase;
extern NSString* const kTCGBErrorUserInfoTransactionId;
extern NSInteger const kTCGBDetailErrorNotExist;

/** TCGBError class represents a result of some APIs or an occurred error.
 */
@interface TCGBError : NSError

/**---------------------------------------------------------------------------------------
 * @name Initialization
 *  ---------------------------------------------------------------------------------------
 */

/**
 Creates TCGBError instance.
 
 @param code error code
*/
+ (TCGBError *)resultWithCode:(NSInteger)code
    NS_SWIFT_NAME(result(code:));

/**
 Creates TCGBError instance.
 
 @param code error code.
 @param message error message.
 */
+ (TCGBError *)resultWithCode:(NSInteger)code message:(NSString *)message
    NS_SWIFT_NAME(result(code:message:));

/**
 Creates TCGBError instance.
 
 @param domain error domain.
 @param code error code.
 @param userInfo a dictionary with userInfo.
 */
+ (TCGBError *)resultWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(nullable NSDictionary<NSErrorUserInfoKey, id> *)userInfo
    NS_SWIFT_NAME(result(domain:code:userInfo:));

/**
 Create TCGBError instance. If the description value is nil or empty string, it will be set a value to default error message.
 
 @param domain domain error domain.
 @param code error code.
 @param description description about error. If it's value is set to nil or empty.
 @param underlyingError error object what a cause of error.
 */
+ (TCGBError *)resultWithDomain:(NSString *)domain code:(NSInteger)code description:(nullable NSString *)description underlyingError:(nullable NSError *)underlyingError
    NS_SWIFT_NAME(result(domain:code:description:underlyingError:));

+ (instancetype)initWithDomain:(NSString *)domain code:(TCGBErrorCode)code description:(NSString *)description
    NS_SWIFT_NAME(init(domain:code:description:));

+ (instancetype)initWithDomain:(NSString *)domain code:(TCGBErrorCode)code description:(NSString *)description underlyingError:(nullable NSError *)underlyingError
    NS_SWIFT_NAME(init(domain:code:description:underlyingError:));

+ (NSError *)errorWithError:(NSError *)error transactionId:(NSString *)transactionId
    NS_SWIFT_NAME(error(_:transactionId:));

/**---------------------------------------------------------------------------------------
 * @name Properties
 *  ---------------------------------------------------------------------------------------
 */

/**
 Error message
 */
- (NSString *)message
    NS_SWIFT_NAME(message());

/**
 Pretty JSON string
 */
- (NSString *)prettyJsonString
    NS_SWIFT_NAME(prettyJsonString());

/**
 JSON string
 */
- (NSString *)jsonString
    NS_SWIFT_NAME(jsonString());

/**
 DetailError using underlyingError
 */
- (nullable NSError *)detailError
    NS_SWIFT_NAME(detailError());

/**
 DetailError error code using underlyingError
 
 If the detailed error code does not exist, kTCGBDetailErrorNotExist is returned.
 */
- (NSInteger)detailErrorCode
    NS_SWIFT_NAME(detailErrorCode());

/**
 DetailError error domain using underlyingError
 */
- (nullable NSString *)detailErrorDomain
    NS_SWIFT_NAME(detailErrorDomain());

/**
 DetailError error message using underlyingError
 */
- (nullable NSString *)detailErrorMessage
    NS_SWIFT_NAME(detailErrorMessage());

/**
 Error UUID
 */
- (nullable NSString *)exceptionId
    NS_SWIFT_NAME(exceptionId());

@end

NS_ASSUME_NONNULL_END

#endif /* TCGBError_h */
