/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import <WeexSDK/WXDefine.h>
#import <WeexSDK/WXType.h>
#import <WeexSDK/WXLog.h>
#import <WeexSDK/WXSDKInstance.h>

// The default screen width which helps us to calculate the real size or scale in different devices.
static const CGFloat WXDefaultScreenWidth = 750.0;

#define WX_ENUMBER_CASE(_invoke, idx, code, obj, _type, op, _flist) \
case code:{\
    _type *_tmp = malloc(sizeof(_type));\
    memset(_tmp, 0, sizeof(_type));\
    *_tmp = [obj op];\
    [_invoke setArgument:_tmp atIndex:(idx) + 2];\
    *(_flist + idx) = _tmp;\
    break;\
}
#define WX_EPCHAR_CASE(_invoke, idx, code, obj, _type, op, _flist) \
case code:{\
    _type *_tmp = (_type  *)[obj op];\
    [_invoke setArgument:&_tmp atIndex:(idx) + 2];\
    *(_flist + idx) = 0;\
    break;\
}\

#define WX_ALLOC_FLIST(_ppFree, _count) \
do {\
    _ppFree = (void *)malloc(sizeof(void *) * (_count));\
    memset(_ppFree, 0, sizeof(void *) * (_count));\
} while(0)

#define WX_FREE_FLIST(_ppFree, _count) \
do {\
    for(int i = 0; i < (_count); i++){\
        if(*(_ppFree + i ) != 0) {\
            free(*(_ppFree + i));\
        }\
    }\
    free(_ppFree);\
}while(0)

#define WX_ARGUMENTS_SET(_invocation, _sig, idx, _obj, _ppFree) \
do {\
    const char *encode = [_sig getArgumentTypeAtIndex:(idx) + 2];\
    switch(encode[0]){\
        WX_EPCHAR_CASE(_invocation, idx, _C_CHARPTR, _obj, char *, UTF8String, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_INT, _obj, int, intValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_SHT, _obj, short, shortValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_LNG, _obj, long, longValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_LNG_LNG, _obj, long long, longLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_UCHR, _obj, unsigned char, unsignedCharValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_UINT, _obj, unsigned int, unsignedIntValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_USHT, _obj, unsigned short, unsignedShortValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG, _obj, unsigned long, unsignedLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_ULNG_LNG, _obj,unsigned long long, unsignedLongLongValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_FLT, _obj, float, floatValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_DBL, _obj, double, doubleValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_BOOL, _obj, bool, boolValue, _ppFree)\
        WX_ENUMBER_CASE(_invocation, idx, _C_CHR, _obj, char, charValue, _ppFree)\
        default: { [_invocation setArgument:&_obj atIndex:(idx) + 2]; *(_ppFree + idx) = 0; break;}\
    }\
}while(0)

#define WXPointEqualToPoint __WXPointEqualToPoint
CG_INLINE bool
__WXPointEqualToPoint(CGPoint point1, CGPoint point2)
{
    return fabs (point1.x - point2.x) < 0.00001 && fabs (point1.y - point2.y) < 0.00001;
}

#ifdef __cplusplus
extern "C" {
#endif
    
/**
 * @abstract execute asynchronous action block on the main thread.
 *
 */
void WXPerformBlockOnMainThread( void (^ _Nonnull block)(void));

/**
 * @abstract execute synchronous action block on the main thread.
 *
 */
void WXPerformBlockSyncOnMainThread( void (^ _Nonnull block)(void));

/**
 * @abstract execute action block on the specific thread.
 *
 */
void WXPerformBlockOnThread(void (^ _Nonnull block)(void), NSThread *_Nonnull thread);

/**
 * @abstract swizzling methods.
 *
 */
void WXSwizzleInstanceMethod(_Nonnull Class className, _Nonnull SEL original, _Nonnull SEL replaced);

void WXSwizzleInstanceMethodWithBlock(_Nonnull Class className, _Nonnull SEL original, _Nonnull id block, _Nonnull SEL replaced);

_Nonnull SEL WXSwizzledSelectorForSelector(_Nonnull SEL selector);
    
#ifdef __cplusplus
}
#endif

@interface WXUtility : NSObject

+ (void)performBlock:(void (^_Nonnull)(void))block onThread:(NSThread *_Nonnull)thread;

/**
 * @abstract Returns the environment of current application, you can get some necessary properties such as appVersion、sdkVersion、appName etc.
 *
 * @return A dictionary object which contains these properties.
 *
 */
+ (NSDictionary *_Nonnull)getEnvironment;

+ (NSDictionary *_Nonnull)getDebugEnvironment;

+ (WXLayoutDirection)getEnvLayoutDirection;

/**
 * @abstract UserAgent Generation
 *
 * @return A ua string by splicing (deviceName、appVersion、sdkVersion、externalField、screenSize)
 *
 */
+ (NSString *_Nonnull)userAgent;

/**
 * @abstract JSON Decode Method
 *
 * @param json String.
 *
 * @return A json object by decoding json string.
 *
 */
+ (id _Nullable)objectFromJSON:(NSString * _Nonnull)json;

/**
 Convert all sub-structure objects of source to immutable container.

 @param source Source object.
 @return Converted object using immutable container.
 */
+ (id _Nullable)convertContainerToImmutable:(id _Nullable)source;

#define WXDecodeJson(json)  [WXUtility objectFromJSON:json]

/**
 * @abstract JSON Encode Method
 *
 * @param object Object.
 *
 * @return A json string by encoding json object.
 *
 */
+ (NSString * _Nullable)JSONString:(id _Nonnull)object;

#define WXEncodeJson(obj)  [WXUtility JSONString:obj]

/**
 * @abstract Returns a Foundation object from given JSON data. A Foundation object from the JSON data in data, or nil if an error occurs.
 *
 * @param data A data object containing JSON data.
 * @param error If an error occurs, upon return contains an NSError object that describes the problem.
 *
 * @return A Foundation object from the JSON data in data, or nil if an error occurs.
 *
 */
+ (id _Nullable)JSONObject:(NSData * _Nonnull)data error:(NSError * __nullable * __nullable)error;

#define WXJSONObjectFromData(data) [WXUtility JSONObject:data error:nil]
/**
 * @abstract JSON Object Copy Method
 *
 * @param object Object.
 *
 * @return A json object by copying.
 *
 */
+ (id _Nullable)copyJSONObject:(id _Nonnull)object;

#define WXCopyJson(obj)     [WXUtility copyJSONObject:obj]

/**
 *
 *  Checks if a String is whitespace, empty ("") or nil
 *  @code
 *    [WXUtility isBlankString: nil]       = true
 *    [WXUtility isBlankString: ""]        = true
 *    [WXUtility isBlankString: " "]       = true
 *    [WXUtility isBlankString: "bob"]     = false
 *    [WXUtility isBlankString: "  bob  "] = false
 *  @endcode
 *  @param string the String to check, may be null
 *
 *  @return true if the String is null, empty or whitespace
 */
+ (BOOL)isBlankString:(NSString * _Nullable)string ;


/**
 check a point is valid or not. A zero point is also valid

 @param point a point value to check
 @return true if point.x and point.y are all valid value for a number.
 */
+ (BOOL)isValidPoint:(CGPoint)point;

/**
 * @abstract Returns a standard error object
 *
 * @param code code.
 *
 * @param message message.
 *
 * @return A error object type of NSError.
 *
 */
+ (NSError * _Nonnull)errorWithCode:(NSInteger)code message:(NSString * _Nullable)message;

/**
 * @abstract Returns a Font Object by setting some properties such as size、weight、style and fontFamily.
 *
 * @param size font size
 *
 * @param textWeight font weight
 *
 * @param textStyle  The type of WXTextStyle (Normal or Italic).
 *
 * @param fontFamily font family
 *
 * @param scaleFactor please use instance's scale factor
 *
 * @return A font object according to the above params.
 *
 */
+ (UIFont *_Nonnull)fontWithSize:(CGFloat)size textWeight:(CGFloat)textWeight textStyle:(WXTextStyle)textStyle fontFamily:(NSString *_Nullable)fontFamily scaleFactor:(CGFloat)scaleFactor;

+ (UIFont *_Nonnull)fontWithSize:(CGFloat)size textWeight:(CGFloat)textWeight textStyle:(WXTextStyle)textStyle fontFamily:(NSString *_Nullable)fontFamily scaleFactor:(CGFloat)scaleFactor useCoreText:(BOOL)useCoreText;

/**
 * @abstract download remote font from specified url
 * @param fontURL for remote font
 *
 */
+ (void)getIconfont:(NSURL * _Nonnull)fontURL completion:( void(^ _Nullable )(NSURL * _Nonnull url, NSError * _Nullable error)) completionBlock;

/**
 * @abstract Returns the main screen's size when the device is in portrait mode,.
 */
+ (CGSize)portraitScreenSize;

/**
 * @abstract Returns the default pixel scale factor
 * @discussion If orientation is equal to landscape, the value is caculated as follows: WXScreenSize().height / WXDefaultScreenWidth, otherwise, WXScreenSize().width / WXDefaultScreenWidth.
 */
+ (CGFloat)defaultPixelScaleFactor;

#if defined __cplusplus
extern "C" {
#endif
/**
 * @abstract Returns the scale of the main screen.
 *
 */
CGFloat WXScreenScale(void);

/**
 * @abstract Returns a Round float coordinates to the main screen pixel.
 *
 */
CGFloat WXRoundPixelValue(CGFloat value);

/**
 * @abstract Returns a Floor float coordinates to the main screen pixel.
 *
 */
CGFloat WXFloorPixelValue(CGFloat value);

/**
 * @abstract Returns a Ceil float coordinates to the main screen pixel.
 *
 */
CGFloat WXCeilPixelValue(CGFloat value);
    
#if defined __cplusplus
};
#endif
    
/**
 *  @abstract check whether the file is exist
 *
 */

+ (BOOL)isFileExist:(NSString * _Nonnull)filePath;
/**
 *  @abstract Returns the document directory path.
 *
 */
+ (NSString *_Nonnull)documentDirectory;

#define WXDocumentPath     [WXUtility documentDirectory]

/**
 *  @abstract Returns the system cache directory path.
 *
 */
+ (NSString *_Nonnull)cacheDirectory;

#define WXCachePath     [WXUtility cacheDirectory]

/**
 *  @abstract Returns the system library directory path.
 *
 */
+ (NSString *_Nonnull)libraryDirectory;

#define WXLibraryPath  [WXUtility libraryDirectory]

/**
 *  @abstract Returns the global cache whose size is 5M.
 *
 */
+ (NSCache *_Nonnull)globalCache;

#define WXGlobalCache   [WXUtility globalCache]

+ (NSURL *_Nonnull)urlByDeletingParameters:(NSURL *_Nonnull)url;

/**
 *  @abstract Returns the contents of file.
 *
 */
+ (NSString *_Nullable)stringWithContentsOfFile:(NSString *_Nonnull)filePath;

/**
 *  @abstract Returns md5 string.
 *
 */
+ (NSString *_Nullable)md5:(NSString *_Nullable)string;

/**
 *  @abstract Returns Creates a Universally Unique Identifier (UUID) string.
 *
 */
+ (NSString *_Nullable)uuidString;

/**
 *  @abstract convert date string with formatter yyyy-MM-dd to date.
 *
 */
+ (NSDate *_Nullable)dateStringToDate:(NSString *_Nullable)dateString;

/**
 *  @abstract convert time string with formatter HH:mm to date.
 *
 */
+ (NSDate *_Nullable)timeStringToDate:(NSString *_Nullable)timeString;

/**
 *  @abstract convert date to date string with formatter yyyy-MM-dd .
 *
 */
+ (NSString *_Nullable)dateToString:(NSDate *_Nullable)date;

/**
 *  @abstract convert date to time string with formatter HH:mm .
 *
 */
+ (NSString *_Nullable)timeToString:(NSDate *_Nullable)date;

/**
 *  @abstract get the repeat substring number of string.
 *
 */
+ (NSUInteger)getSubStringNumber:(NSString *_Nullable)string subString:(NSString *_Nullable)subString;

/**
 *  @abstract Returns a resized pixel which is calculated according to the WXScreenResizeRadio.
 *
 */
CGFloat WXPixelScale(CGFloat value, CGFloat scaleFactor);

CGFloat WXScreenResizeRadio(void) DEPRECATED_MSG_ATTRIBUTE("Use [WXUtility defaultPixelScaleFactor] instead");
CGFloat WXPixelResize(CGFloat value) DEPRECATED_MSG_ATTRIBUTE("Use WXPixelScale Instead");
CGRect WXPixelFrameResize(CGRect value) DEPRECATED_MSG_ATTRIBUTE("Use WXPixelScale Instead");
CGPoint WXPixelPointResize(CGPoint value) DEPRECATED_MSG_ATTRIBUTE("Use WXPixelScale Instead");
+ (UIFont  * _Nullable )fontWithSize:(CGFloat)size textWeight:(CGFloat)textWeight textStyle:(WXTextStyle)textStyle fontFamily:(NSString * _Nullable)fontFamily DEPRECATED_MSG_ATTRIBUTE("Use +[WXUtility fontWithSize:textWeight:textStyle:fontFamily:scaleFactor:]");


/**
 @discusstion construct a gradientLayer from the colors locations, gradientType
 @param colors The array of UIColor objects defining the color of each gradient
 stop. Defaults to nil
 @param locations An optional array of NSNumber objects defining the location of each
  gradient stop as a value in the range [0,1].
 @param frame the layer frame
 @param gradientType WXGradientType value specify the gradient location
 @return gradient layer
 */
+ (CAGradientLayer *_Nullable)gradientLayerFromColors:(NSArray*_Nullable)colors
                                           locations:(NSArray*_Nullable)locations
                                               frame:(CGRect)frame
                                        gradientType:(WXGradientType)gradientType;

/**
 @discusstion parse gradient-color string to a dictionary, then you can get gradientLayer from @see gradientLayerFromColors:colors:locations:frame:locations
 @param backgroundImage  linear-gradient string like linear-gradient(to right, #a80077,rgba(200, 54, 54, 0.5))
 @return dictionary with endColor, startColor and gradientType value
 @code
    NSDictionary * linearGradient = [self linearGradientWithBackgroundImage:@"linear-gradient(to right, #a80077,rgba(200, 54, 54, 0.5))"];
    CAGradientLayer * gradientLayer = [self gradientLayerFromColors:@[linearGradient[@"startColor"], linearGradient[@"endColor"]],nil,bounds,[linearGradient[@"gradientType"] integerValue]];
 @endcode
 */
+ (NSDictionary *_Nullable)linearGradientWithBackgroundImage:(NSString *_Nullable)backgroundImage;

#if defined __cplusplus
extern "C" {
#endif
    
/**
 *  @abstract compare float a and b, if a equal b, return true,or reture false.
 *
 */
BOOL WXFloatEqual(CGFloat a, CGFloat b);
/**
 *  @abstract compare float a and b, user give the compare precision, if a equal b, return true,or reture false.
 *
 */
BOOL WXFloatEqualWithPrecision(CGFloat a, CGFloat b ,double precision);
/**
 *  @abstract compare float a and b, if a less than b, return true,or reture false.
 *
 */
BOOL WXFloatLessThan(CGFloat a, CGFloat b);
/**
 *  @abstract compare float a and b,user give the compare precision, if a less than b,return true,or reture false.
 *
 */
BOOL WXFloatLessThanWithPrecision(CGFloat a, CGFloat b,double precision);
/**
 *  @abstract compare float a and b, if a great than b, return true,or reture false.
 *
 */
BOOL WXFloatGreaterThan(CGFloat a, CGFloat b);
/**
 *  @abstract compare float a and b, user give the compare precision,if a great than b, return true,or reture false.
 *
 */
BOOL WXFloatGreaterThanWithPrecision(CGFloat a,CGFloat b,double precision);

#if defined __cplusplus
};
#endif

/**
 *  @abstract convert returnKeyType to type string .
 *
 */
+ (NSString *_Nullable)returnKeyType:(UIReturnKeyType)type;

/**
 *  @abstract custorm monitor info
 *
 */
+ (void)customMonitorInfo:(WXSDKInstance *_Nullable)instance key:(NSString * _Nonnull)key value:(id _Nonnull)value;

/**
 *  @abstract format to base64 dictionary
 *
 */
+ (NSDictionary *_Nonnull)dataToBase64Dict:(NSData *_Nullable)data;

/**
 *  @abstract format to data
 *
 */
+ (NSData *_Nonnull)base64DictToData:(NSDictionary *_Nullable)base64Dict;

+ (void)setEnableRTLLayoutDirection:(BOOL)value;

+ (BOOL)enableRTLLayoutDirection;

+ (long) getUnixFixTimeMillis;

+ (NSArray<NSString *> *_Nullable)extractPropertyNamesOfJSValueObject:(JSValue *_Nullable)jsvalue;

@end
