//
//  TCGBUtil.h
//  Gamebase
//
//  Created by NHN on 2016. 6. 30..
//  © NHN Corp. All rights reserved.
//

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

#ifndef TCGBUTIL_H
#define TCGBUTIL_H

NS_ASSUME_NONNULL_BEGIN

#define LOG_VERBOSE(s, ...) do {\
[TCGBUtil logVerboseWithFormat:@"[%@:(%d)] %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]]; \
} while (0)

#define LOG_DEBUG(s, ...) do {\
[TCGBUtil logDebugWithFormat:@"🐞[%@:(%d)] %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]]; \
} while (0)

#define LOG_INFO(s, ...) do {\
[TCGBUtil logInfoWithFormat:@"ℹ️[%@:(%d)] %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]]; \
} while (0)

#define LOG_WARN(s, ...) do {\
[TCGBUtil logWarnWithFormat:@"⚠️[%@:(%d)] %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]]; \
} while (0)

#define LOG_ERROR(s, ...) do {\
[TCGBUtil logErrorWithFormat:@"❗️[%@:(%d)] %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]]; \
} while (0)

typedef void(^alertActionBlock)(id buttonTitle);
typedef void(^alertActionHandler)(UIAlertAction *action);

/** The TCGBUtil class provides convenient and useful methods.
 */
@interface TCGBUtil : NSObject

#pragma mark - Gamebase Informations
/**---------------------------------------------------------------------------------------
 * @name Utilities
 *  ---------------------------------------------------------------------------------------
 */

/**
 @return Gamebase Config Information
 */
+ (NSString *)appVersion
    NS_SWIFT_NAME(appVersion());

/**
 @return Gamebase Version
 */
+ (NSString *)gamebaseVersion
    NS_SWIFT_NAME(gamebaseVersion());

+ (NSString *)getLocalizedStringForKey:(NSString *)key
    NS_SWIFT_NAME(getLocalizedString(key:));

#pragma mark - Device Informations
/**
 @return App Tracking AuthorizationStatus
 */
+ (TCGBAppTrackingAuthorizationStatus)appTrackingAuthorizationStatus;

/**
 @return IDFA, Advertising Identifier.
 */
+ (NSString *)idfa
    NS_SWIFT_NAME(idfa());

/**
 @return IDFV, Vendor Identifier.
 */
+ (NSString *)idfv
    NS_SWIFT_NAME(idfv());

/**
 @return UUID, 4 random bytes string.
 */
+ (NSString *)uuid
    NS_SWIFT_NAME(uuid());

/**
 @return OS Code, actually "IOS".
 */
+ (NSString *)osCode
    NS_SWIFT_NAME(osCode());

/**
 @return OS Version.
 */
+ (NSString *)osVersion
    NS_SWIFT_NAME(osVersion());

/**
 @return OS Version dot-formatted.
 */
+ (NSArray<NSString *> *)osVersionSeperatedByDot
    NS_SWIFT_NAME(osVersionSeperatedByDot());

/**
 @return `YES` if majorVersion is greater than or equal to majorVersion.
 @param majorVersion version to be compared with OS version.
 @param later if this value sets YES, it returns whether OS version is greater than or equal to majorVersion.
 */
+ (BOOL)isiOSVersion:(int)majorVersion orLater:(BOOL)later
    NS_SWIFT_NAME(isiOSVersion(_:orLater:))
    DEPRECATED_MSG_ATTRIBUTE("This API will be removed in the future.");

/**
 @return Device model.
 */
+ (NSString *)deviceModel
    NS_SWIFT_NAME(deviceModel());

/**
 @return Detail Device model.
 */
+ (NSString *)detailDeviceModel
    NS_SWIFT_NAME(detailDeviceModel());

/**
 @return Preferred launguage.
 @since Added 1.14.0.
 */
+ (NSString *)deviceLanguageCode
    NS_SWIFT_NAME(deviceLanguageCode());

/**
 @return language code by NSLocaleLanguageCode of NSLocale. (ex. "en", "ko", "ja", "zh", "vi")
 */
+ (NSString *)deviceLocaleLanguageCode
    NS_SWIFT_NAME(deviceLocaleLanguageCode());

/**
 @return Locale country code is returned.
 */
+ (NSString *)deviceCountryCode
    NS_SWIFT_NAME(deviceCountryCode());

#pragma mark - app informations
/**
 @return Main bundle's identifier.
 */
+ (NSString *)bundleID
    NS_SWIFT_NAME(bundleID());

/**
 @return DisplayName.
 */
+ (NSString *)displayName
    NS_SWIFT_NAME(displayName());

#pragma mark - Data & Time
/**
 @return Unix epoch time, it is millisecods, 13 digits.
 */
+ (uint64_t)unixEpochTime
    NS_SWIFT_NAME(unixEpochTime());

#pragma mark - JSON
/**
 @return value object which is in the json formatted dictionary and have a dottedString key.
 
    ## Example
    NSDictionary json;
    json = @{
        @"key1" : @"value1",
        @"key2" : @{
            @"key2-1" : @"value2-1",
            @"key2-2" : @[@"value2-2[0]", @"value2-2[1]"]
        },
        @"key3" : @"value3"
    }
 
    NSString *dottedString = @"key2.key2-2[1]";
    NSString *extractedString = [TCGBUtil extractValueFrom:json searchString:dottedString];
    NSLog(@"%@", extractedString);
    // It would be > "value2-2[1]"
 
 */
+ (id)extractValueFrom:(NSDictionary *)json searchString:(NSString *)dottedString
    NS_SWIFT_NAME(extractValue(fromJson:searchString:));

/**
 @return Returns an object converted from json string to dictionary.
 */
+ (nullable NSDictionary *)dictionaryFrom:(NSString *)jsonString
    NS_SWIFT_NAME(dictionary(fromJsonString:));

#pragma mark - Encoding
/**---------------------------------------------------------------------------------------
 * @name Encoding
 *  ---------------------------------------------------------------------------------------
 */

/**
 @return `YES` if the targetString is URL encoded.
 */
+ (BOOL)isURLEncoded:(NSString *)targetString
    NS_SWIFT_NAME(isURLEncoded(_:));

/**
 @return URL Encoded String.
 @param string The string to be encoded.
 */
+ (nullable NSString *)URLEncodedString:(NSString *)string
    NS_SWIFT_NAME(URLEncodedString(_:));

/**
 @return URL Encoded String.
 @param data The data to be encoded.
 */
+ (nullable NSString *)URLEncodedStringWithData:(NSData *)data
    NS_SWIFT_NAME(URLEncodedString(data:));

#pragma mark - System UI
/**---------------------------------------------------------------------------------------
 * @name System UI
 *  ---------------------------------------------------------------------------------------
 */

/**
 Show Toast.
 
 @param message The message to be shown in the toast.
 @param length The time interval to be exposed. GamebaseToastLengthLong (3.5 seconds), GamebaseToastLengthShort (2 seconds)
 */
+ (void)showToastWithMessage:(NSString *)message length:(GamebaseToastLength)length
    NS_SWIFT_NAME(showToast(message:length:));

/**
 Show Alert View with async completion handler

 @param viewController The viewController that will display the alert
 @param title The title of alert
 @param message The message of alert
 @param completion The callback of alert when user has tapped the 'OK(확인)' button
 */
+ (void)showAlertWithViewController:(UIViewController *)viewController title:(nullable NSString *)title message:(nullable NSString *)message  completion:(void(^ _Nullable)(void))completion
    NS_SWIFT_NAME(showAlert(_:title:message:completion:));
/**
 Show Alert View with async completion handler

 @param title The title of alert
 @param message The message of alert
 @param completion The callback of alert when user has tapped the 'OK(확인)' button
 */
+ (void)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message completion:(void(^ _Nullable)(void))completion
    NS_SWIFT_NAME(showAlert(title:message:completion:));

/**
 Show Alert View
 
 @param title The title of alert
 @param message The message of alert
 */
+ (void)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message
    NS_SWIFT_NAME(showAlert(title:message:));

+ (void)showActionSheetWithTitle:(nullable NSString *)title message:(nullable NSString *)message blocks:(NSDictionary<NSString *, alertActionHandler> *)blocks
    NS_SWIFT_NAME(showActionSheet(title:message:blocks:));

+ (UIViewController *)topMostViewController
    NS_SWIFT_NAME(topMostViewController());

#pragma mark - Log
/**---------------------------------------------------------------------------------------
 * @name Logging
 *  ---------------------------------------------------------------------------------------
 */

/**
 Verbose Log
 
 @param format Log
 */
+ (void)logVerboseWithFormat:(NSString *)format, ...;

/**
 Debug Log
 
 @param format Log
 */
+ (void)logDebugWithFormat:(NSString *)format, ...;

/**
 Info Log
 
 @param format Log
 */
+ (void)logInfoWithFormat:(NSString *)format, ...;

/**
 Warning Log
 
 @param format Log
 */
+ (void)logWarnWithFormat:(NSString *)format, ...;

/**
 Error Log
 
 @param format Log
 */
+ (void)logErrorWithFormat:(NSString *)format, ...;

/**
 Log
 
 @param logString Log
 */
+ (void)logWithString:(NSString *)logString;

/**
 OS Log
 
 @param newString Log
 */
+ (void)osLog:(NSString *)newString;

+ (NSInteger)SDKLogLevel;


#pragma mark - Etc
/**---------------------------------------------------------------------------------------
 * @name Etc
 *  ---------------------------------------------------------------------------------------
 */

/**
 Convert color hex string to UIColor
 
 @return UIColor.
 @param hexString  The color hex string  such as #RGB, #ARGB, #RRGGBB, #RRGGBBAA.
 */

+ (UIColor *)colorFromHexString:(NSString *)hexString;

@end


@interface TCGBUtil (deprecated)

/**
 @since Added 1.4.0.
 @deprecated As of release 1.14.0, use deviceLanguageCode method instead.
 */
+ (NSString *)deviceLanguage DEPRECATED_MSG_ATTRIBUTE("Use deviceLanguageCode method instead.");

/**
 @return ISO country code. First, usimCountryCode is returned, if there is not usim, deviceCountryCode is returned.
 @see usimCountryCode
 @see deviceCountryCode
 @since Added 1.4.0.
 @deprecated As of release 1.14.0, use countryCode method instead.
 */
+ (NSString *)country DEPRECATED_MSG_ATTRIBUTE("Use countryCode method instead.");

/**
 @return ISO country code. First, usimCountryCode is returned, if there is not usim, deviceCountryCode is returned.
 @see usimCountryCode
 @see deviceCountryCode
 @since Added 1.14.0.
 @deprecated As of release 2.52.0, use deviceCountryCode method instead.
 */
+ (NSString *)countryCode
    NS_SWIFT_NAME(countryCode())
    DEPRECATED_MSG_ATTRIBUTE("Use deviceCountryCode method instead.");

/**
 @return Usim country code is returned. If there is not usim, 'ZZ' is returned.
 @since Added 1.4.0.
 @deprecated As of release 2.52.0, returns 'ZZ' since iOS 16.4.
 */
+ (NSString *)usimCountryCode
    NS_SWIFT_NAME(usimCountryCode())
    DEPRECATED_MSG_ATTRIBUTE("Returns 'ZZ' since iOS 16.4.");

/**
 @return Cellular service provider's code.
 @since Added 1.4.0.
 @deprecated As of release 2.52.0, returns nil since iOS 16.4.
 */
+ (NSString *)carrierCode
    NS_SWIFT_NAME(carrierCode())
    DEPRECATED_MSG_ATTRIBUTE("Returns nil since iOS 16.4.");

/**
 @return Cellular service provider's name.
 @since Added 1.4.0.
 @deprecated As of release 2.52.0, returns nil since iOS 16.4.
 */
+ (NSString *)carrierName
    NS_SWIFT_NAME(carrierName())
    DEPRECATED_MSG_ATTRIBUTE("Returns nil since iOS 16.4.");

@end

NS_ASSUME_NONNULL_END

#endif

