/*
 * 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 "WXTextComponent.h"
#import "WXSDKInstance_private.h"
#import "WXComponent_internal.h"
#import "WXLayer.h"
#import "WXUtility.h"
#import "WXConvert.h"
#import "WXRuleManager.h"
#import "WXDefine.h"
#import "WXView.h"
#import "WXComponent+Layout.h"
#import <pthread/pthread.h>
#import <CoreText/CoreText.h>

// WXText is a non-public is not permitted
@interface WXTextView : WXView
@property (nonatomic, strong) NSTextStorage *textStorage;
@end

@implementation WXTextView

- (instancetype)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame])) {
        self.accessibilityTraits |= UIAccessibilityTraitStaticText;
        
        self.opaque = NO;
        self.contentMode = UIViewContentModeRedraw;
        self.textStorage = [NSTextStorage new];
    }
    return self;
}

+ (Class)layerClass
{
    return [WXLayer class];
}

- (void)copy:(id)sender
{
    [[UIPasteboard generalPasteboard] setString:((WXTextComponent*)self.wx_component).text];
}

- (void)setTextStorage:(NSTextStorage *)textStorage
{
    if (_textStorage != textStorage) {
        _textStorage = textStorage;
        [self.wx_component setNeedsDisplay];
    }
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:)) {
        return [[self.wx_component valueForKey:@"_enableCopy"] boolValue];
    }
    return [super canPerformAction:action withSender:sender];
}

- (NSString *)description
{
    NSString *superDescription = super.description;
    NSRange semicolonRange = [superDescription rangeOfString:@";"];
    NSString * content = _textStorage.string;
    if ([(WXTextComponent*)self.wx_component useCoreText]) {
        content = ((WXTextComponent*)self.wx_component).text;
    }
    NSString *replacement = [NSString stringWithFormat:@"; text: %@; frame:%f,%f,%f,%f", content, self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height];
    return [superDescription stringByReplacingCharactersInRange:semicolonRange withString:replacement];
}

- (NSString *)accessibilityValue
{
    if (self.wx_component && self.wx_component->_ariaLabel) {
        return [super accessibilityValue];
    }
    if (![(WXTextComponent*)self.wx_component useCoreText]) {
        return _textStorage.string;
    }
    return ((WXTextComponent*)self.wx_component).text;
}

- (NSString *)accessibilityLabel
{
    if (self.wx_component) {
        if (self.wx_component->_ariaLabel) {
            return self.wx_component->_ariaLabel;
        }
    }
    return [super accessibilityLabel];
}

@end

static NSString *const WXTextTruncationToken = @"\u2026";
static CGFloat WXTextDefaultLineThroughWidth = 1.2;

@interface WXTextComponent()
@property (atomic, strong) NSString *fontFamily;
@property (atomic, strong) UIColor *textColor;
@property (atomic, strong) UIColor *darkThemeTextColor;
@end

@implementation WXTextComponent
{
    UIEdgeInsets _border;
    UIEdgeInsets _padding;
    NSTextStorage *_textStorage;
    float _textStorageWidth;
    float _fontSize;
    float _fontWeight;
    WXTextStyle _fontStyle;
    NSUInteger _lines;
    NSTextAlignment _textAlign;
    WXTextDecoration _textDecoration;
    NSString *_textOverflow;
    float _lineHeight;
    float _letterSpacing;
    float _fontDescender;
    float _fontAscender;
    BOOL _truncationLine; // support trunk tail
    
    NSAttributedString * _ctAttributedString;
    NSString *_wordWrap;
    
    pthread_mutex_t _ctAttributedStringMutex;
    pthread_mutexattr_t _propertMutexAttr;
    BOOL _observerIconfont;
    BOOL _enableCopy;
    
    BOOL _useCoreText;
}

- (instancetype)initWithRef:(NSString *)ref
                       type:(NSString *)type
                     styles:(NSDictionary *)styles
                 attributes:(NSDictionary *)attributes
                     events:(NSArray *)events
               weexInstance:(WXSDKInstance *)weexInstance
{
    self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
    if (self) {
        // just for coretext and textkit render replacement
        pthread_mutexattr_init(&(_propertMutexAttr));
        pthread_mutexattr_settype(&(_propertMutexAttr), PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(&(_ctAttributedStringMutex), &(_propertMutexAttr));
        
        _textAlign = NSTextAlignmentNatural;
        
        if ([attributes objectForKey:@"coretext"]) {
            _useCoreText = [WXConvert BOOL:attributes[@"coretext"]];
        } else {
            _useCoreText = YES;
        }

        [self fillCSSStyles:styles];
        [self fillAttributes:attributes];
        
    }
    return self;
}

- (BOOL)useCoreText
{
    return _useCoreText;
}

- (void)dealloc
{
    if (self.fontFamily && _observerIconfont) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:WX_ICONFONT_DOWNLOAD_NOTIFICATION object:nil];
    }
    pthread_mutex_destroy(&_ctAttributedStringMutex);
    pthread_mutexattr_destroy(&_propertMutexAttr);
}

#define WX_STYLE_FILL_TEXT(key, prop, type, needLayout)\
do {\
    id value = styles[@#key];\
    if (value) {\
        _##prop = [WXConvert type:value];\
        [self setNeedsRepaint];\
        if (needLayout) {\
            [self setNeedsLayout];\
        }\
    }\
} while(0);

#define WX_STYLE_FILL_TEXT_WITH_DEFAULT_VALUE(key, prop, type, defaultValue,needLayout)\
do {\
    id value = styles[@#key];\
    if (value) {\
        if([WXUtility isBlankString:value]){\
            _##prop = defaultValue;\
        }else {\
            _##prop = [WXConvert type:value];\
        }\
        [self setNeedsRepaint];\
        if (needLayout) {\
            [self setNeedsLayout];\
        }\
    }\
} while(0);


#define WX_STYLE_FILL_TEXT_PIXEL(key, prop, needLayout)\
do {\
    id value = styles[@#key];\
    if (value) {\
        _##prop = [WXConvert WXPixelType:value scaleFactor:self.weexInstance.pixelScaleFactor];\
        [self setNeedsRepaint];\
    if (needLayout) {\
        [self setNeedsLayout];\
    }\
}\
} while(0);

- (void)fillCSSStyles:(NSDictionary *)styles
{
    do {
        id value = styles[@"fontFamily"];
        if (value) {
            self.fontFamily = [WXConvert NSString:value];
            [self setNeedsRepaint];
            [self setNeedsLayout];
        }
    } while(0);
    
    WX_STYLE_FILL_TEXT_PIXEL(fontSize, fontSize, YES) //!OCLint
    WX_STYLE_FILL_TEXT(fontWeight, fontWeight, WXTextWeight, YES) //!OCLint
    WX_STYLE_FILL_TEXT(fontStyle, fontStyle, WXTextStyle, YES) //!OCLint
    WX_STYLE_FILL_TEXT(lines, lines, NSUInteger, YES) //!OCLint
    WX_STYLE_FILL_TEXT(textAlign, textAlign, NSTextAlignment, NO) //!OCLint
    WX_STYLE_FILL_TEXT(textDecoration, textDecoration, WXTextDecoration, YES) //!OCLint
    WX_STYLE_FILL_TEXT(textOverflow, textOverflow, NSString, NO) //!OCLint
    WX_STYLE_FILL_TEXT_PIXEL(lineHeight, lineHeight, YES) //!OCLint
    WX_STYLE_FILL_TEXT_PIXEL(letterSpacing, letterSpacing, YES) //!OCLint
    WX_STYLE_FILL_TEXT(wordWrap, wordWrap, NSString, YES); //!OCLint

    do {
        UIColor* color = nil;
        id value = styles[@"color"];
        if (value) {
            if([WXUtility isBlankString:value]){
                color = [UIColor blackColor];
            } else {
                color = [WXConvert UIColor:value];
            }
            if (color) {
                self.textColor = color;
                [self setNeedsRepaint];
            }
        }
        if (self.textColor == nil) {
            self.textColor = [UIColor blackColor];
        }
    } while (0);

    do {
        UIColor* color = nil;
        id value = styles[@"darkThemeColor"];
        if (value) {
            if([WXUtility isBlankString:value]){
                color = [UIColor blackColor];
            } else {
                color = [WXConvert UIColor:value];
            }
            if (color) {
                self.darkThemeTextColor = color;
                [self setNeedsRepaint];
            }
        }
    } while (0);
    
    if (self.fontFamily && !_observerIconfont) {
        // notification received when custom icon font file download finish
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(repaintText:) name:WX_ICONFONT_DOWNLOAD_NOTIFICATION object:nil];
        _observerIconfont = YES;
    }
    
    if (self.flexCssNode == nullptr) {
        return;
    }
    
        UIEdgeInsets flex_padding = {
            WXFloorPixelValue(self.flexCssNode->getPaddingTop() + self.flexCssNode->getBorderWidthTop()),
            WXFloorPixelValue(self.flexCssNode->getPaddingLeft() + self.flexCssNode->getBorderWidthLeft()),
            WXFloorPixelValue(self.flexCssNode->getPaddingBottom() + self.flexCssNode->getBorderWidthBottom()),
            WXFloorPixelValue(self.flexCssNode->getPaddingRight() + self.flexCssNode->getBorderWidthRight())
        };
        
        if (!UIEdgeInsetsEqualToEdgeInsets(flex_padding, _padding)) {
            _padding = flex_padding;
            [self setNeedsRepaint];
        }
}

- (void)fillAttributes:(NSDictionary *)attributes
{
    id text = [WXConvert NSString:attributes[@"value"]];
    if (text && ![self.text isEqualToString:text]) {
        self.text = text;
        [self setNeedsRepaint];
        [self setNeedsLayout];
    }
    if (attributes[@"enableCopy"]) {
        _enableCopy = [WXConvert BOOL:attributes[@"enableCopy"]];
    }
}

- (void)setNeedsRepaint
{
    _textStorage = nil;
    
    pthread_mutex_lock(&(_ctAttributedStringMutex));
    _ctAttributedString = nil;
    pthread_mutex_unlock(&(_ctAttributedStringMutex));
}

#pragma mark - Subclass

- (void)setNeedsLayout
{
    [super setNeedsLayout];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    BOOL useCoreText = NO;
    if ([self.view.wx_component isKindOfClass:NSClassFromString(@"WXTextComponent")] && [self.view.wx_component respondsToSelector:@selector(useCoreText)]) {
        useCoreText = [(WXTextComponent*)self.view.wx_component useCoreText];
    }
    if (!useCoreText) {
        ((WXTextView *)self.view).textStorage = _textStorage;
    }
    if (_enableCopy) {
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(displayMenuController:)];
        [self.view addGestureRecognizer:longPress];
    }
    self.view.isAccessibilityElement = YES;
    
    [self setNeedsDisplay];
}

- (void)displayMenuController:(id)sender
{
    if ([self.view becomeFirstResponder] && ((UILongPressGestureRecognizer*)sender).state == UIGestureRecognizerStateBegan) {
        UIMenuController *theMenu = [UIMenuController sharedMenuController];
        CGSize size = [self ctAttributedString].size;
        CGRect selectionRect = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, size.width, size.height);
        [theMenu setTargetRect:selectionRect inView:self.view.superview];
        [theMenu setMenuVisible:YES animated:YES];
    }
}

- (UIView *)loadView
{
    return [[WXTextView alloc] init];
}

- (void)layoutDirectionDidChanged:(BOOL)isRTL {
    [self setNeedsRepaint];
}

- (void)themeDidChange:(NSString*)theme
{
    [self setNeedsRepaint];
    [super themeDidChange:theme];
    if (_view) {
        [self setNeedsDisplay];
    }
}

- (WXColorScene)colorSceneType
{
    return WXColorSceneText;
}

- (BOOL)needsDrawRect
{
    return YES;
}

- (UIImage *)drawRect:(CGRect)rect;
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    if (_isCompositingChild) {
        [self drawTextWithContext:context bounds:rect padding:_padding];
    } else {
        [self drawTextWithContext:context bounds:rect padding:_padding];
    }
    
    return nil;
}

- (CGSize (^)(CGSize))measureBlock
{
    __weak typeof(self) weakSelf = self;
    return ^CGSize (CGSize constrainedSize) {
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return CGSizeZero;
        }
        
        if (strongSelf.flexCssNode == nullptr) {
            return CGSizeZero;
        }
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> measureblock %@, constrainedSize:%@",
              self.type,
              NSStringFromCGSize(constrainedSize)
              );
#endif
        CGSize computedSize = CGSizeZero;
        NSTextStorage *textStorage = nil;
        
        //TODO:more elegant way to use max and min constrained size
            if (!isnan(strongSelf.flexCssNode->getMinWidth())) {
                constrainedSize.width = MAX(constrainedSize.width, strongSelf.flexCssNode->getMinWidth());
            }
            
            if (!isnan(strongSelf.flexCssNode->getMaxWidth())) {
                constrainedSize.width = MIN(constrainedSize.width, strongSelf.flexCssNode->getMaxWidth());
            }
        
        if (![self useCoreText]) {
            textStorage = [strongSelf textStorageWithWidth:constrainedSize.width];
            NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
            NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
            computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
        } else {
            computedSize = [strongSelf calculateTextHeightWithWidth:constrainedSize.width];
        }
            if (!isnan(strongSelf.flexCssNode->getMinWidth())) {
                computedSize.width = MAX(computedSize.width, strongSelf.flexCssNode->getMinWidth());
            }
            
            if (!isnan(strongSelf.flexCssNode->getMaxWidth())) {
                computedSize.width = MIN(computedSize.width, strongSelf.flexCssNode->getMaxWidth());
            }
            
            if (!isnan(strongSelf.flexCssNode->getMinHeight())) {
                computedSize.height = MAX(computedSize.height, strongSelf.flexCssNode->getMinHeight());
            }
            
            if (!isnan(strongSelf.flexCssNode->getMaxHeight())) {
                computedSize.height = MIN(computedSize.height, strongSelf.flexCssNode->getMaxHeight());
            }
        if (textStorage && [WXUtility isBlankString:textStorage.string]) {
            //  if the text value is empty or nil, then set the height is 0.
            computedSize.height = 0;
        }
        
        return (CGSize) {
            WXCeilPixelValue(computedSize.width),
            WXCeilPixelValue(computedSize.height)
        };
    };
}

#pragma mark Text Building

- (NSAttributedString *)ctAttributedString
{
    if (!self.text) {
        return nil;
    }
    NSAttributedString * attributedString = nil;
    pthread_mutex_lock(&(_ctAttributedStringMutex));
    if (!_ctAttributedString) {
        _ctAttributedString = [self buildCTAttributeString];
        WXPerformBlockOnComponentThread(^{
            [self.weexInstance.componentManager startComponentTasks];
        });
    }
    attributedString = [_ctAttributedString copy];
    pthread_mutex_unlock(&(_ctAttributedStringMutex));
    return attributedString;
}

- (void)repaintText:(NSNotification *)notification
{
    if (![self.fontFamily isEqualToString:notification.userInfo[@"fontFamily"]]) {
        return;
    }
    [self setNeedsRepaint];
    WXPerformBlockOnComponentThread(^{
        [self.weexInstance.componentManager startComponentTasks];
        WXPerformBlockOnMainThread(^{
            [self setNeedsLayout];
            [self setNeedsDisplay];
        });
    });
}

- (NSMutableAttributedString *)buildCTAttributeString
{
    NSString * string = self.text;
    if (![string isKindOfClass:[NSString class]]) {
        WXLogError(@"text %@ is invalid", self.text);
        string = @"";
    }
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString: string];
    UIColor* textColor = [self.weexInstance chooseColor:self.textColor darkThemeColor:self.darkThemeTextColor invert:self.invertForDarkTheme scene:[self colorSceneType]];
    if (textColor) {
        [attributedString addAttribute:NSForegroundColorAttributeName value:textColor range:NSMakeRange(0, string.length)];
    }
    
    // set font
    UIFont *font = [WXUtility fontWithSize:_fontSize textWeight:_fontWeight textStyle:WXTextStyleNormal fontFamily:self.fontFamily scaleFactor:self.weexInstance.pixelScaleFactor useCoreText:[self useCoreText]];
    CTFontRef ctFont;
    
    if (_fontStyle == WXTextStyleItalic) {
        CGAffineTransform matrix = CGAffineTransformMake(1, 0, tanf(16 * (CGFloat)M_PI / 180), 1, 0, 0);
        ctFont = CTFontCreateWithFontDescriptor((__bridge CTFontDescriptorRef)font.fontDescriptor, font.pointSize, &matrix);
    }else {
        ctFont = CTFontCreateWithFontDescriptor((__bridge CTFontDescriptorRef)font.fontDescriptor, font.pointSize, NULL);
    }
    
    _fontAscender = font.ascender;
    _fontDescender = font.descender;
    
    if (ctFont) {
        [attributedString addAttribute:(id)kCTFontAttributeName value:(__bridge id)(ctFont) range:NSMakeRange(0, string.length)];
        CFRelease(ctFont);
    }
    
    if(_textDecoration == WXTextDecorationUnderline){
        [attributedString addAttribute:(id)kCTUnderlineStyleAttributeName value:@(kCTUnderlinePatternSolid | kCTUnderlineStyleSingle) range:NSMakeRange(0, string.length)];
    } else if(_textDecoration == WXTextDecorationLineThrough){
        [attributedString addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, string.length)];
    }
    
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    
    // handle text direction style, default ltr
    NSTextAlignment retAlign = _textAlign;
    BOOL isRtl = [self isDirectionRTL];
    if (isRtl) {
        if (0 == retAlign) {
            //force text right-align if don't specified any align.
            retAlign = NSTextAlignmentRight;
        }
        paragraphStyle.baseWritingDirection = NSWritingDirectionRightToLeft;
    } else {
        //if you specify NSWritingDirectionNaturalDirection, the receiver resolves the writing
        //directionto eitherNSWritingDirectionLeftToRight or NSWritingDirectionRightToLeft,
        //depending on the direction for the user’s language preference setting.
        paragraphStyle.baseWritingDirection =  NSWritingDirectionNatural;
    }
    
    if (retAlign) {
        paragraphStyle.alignment = retAlign;
    }
    
    if ([[_wordWrap lowercaseString] isEqualToString:@"anywhere"]) {
        paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
    }
    else {
        paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    }
    
    _truncationLine = NO;
    if (_textOverflow && [_textOverflow length] > 0) {
        if (_lines && [_textOverflow isEqualToString:@"ellipsis"])
            _truncationLine = YES;
    }
    
    if (_lineHeight) {
        paragraphStyle.maximumLineHeight = _lineHeight;
        paragraphStyle.minimumLineHeight = _lineHeight;
    }
    if (_lineHeight || _textAlign || [_textOverflow length] > 0) {
        [attributedString addAttribute:NSParagraphStyleAttributeName
                                 value:paragraphStyle
                                 range:(NSRange){0, attributedString.length}];
    }
    
    if (_letterSpacing) {
        [attributedString addAttribute:NSKernAttributeName value:@(_letterSpacing) range:(NSRange){0, attributedString.length}];
    }
    
    return attributedString;
}

- (NSAttributedString *)buildAttributeString
{
    NSString *string = self.text ?: @"";
    
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
    
    // set textColor
    UIColor* textColor = [self.weexInstance chooseColor:self.textColor darkThemeColor:self.darkThemeTextColor invert:self.invertForDarkTheme scene:[self colorSceneType]];
    if (textColor) {
        [attributedString addAttribute:NSForegroundColorAttributeName value:textColor range:NSMakeRange(0, string.length)];
    }
    
    // set font
    UIFont *font = [WXUtility fontWithSize:_fontSize textWeight:_fontWeight textStyle:_fontStyle fontFamily:self.fontFamily scaleFactor:self.weexInstance.pixelScaleFactor];
    if (font) {
        [attributedString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, string.length)];
    }
    
    if(_textDecoration == WXTextDecorationUnderline){
        [attributedString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, string.length)];
    } else if(_textDecoration == WXTextDecorationLineThrough){
        [attributedString addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, string.length)];
    }
    
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];

    // handle text direction style, default ltr
    NSTextAlignment retAlign = _textAlign;
    BOOL isRtl = [self isDirectionRTL];
    if (isRtl) {
        if (0 == retAlign) {
            //force text right-align if don't specified any align.
            retAlign = NSTextAlignmentRight;
        }
        paragraphStyle.baseWritingDirection = NSWritingDirectionRightToLeft;
    } else {
        //if you specify NSWritingDirectionNaturalDirection, the receiver resolves the writing
        //directionto eitherNSWritingDirectionLeftToRight or NSWritingDirectionRightToLeft,
        //depending on the direction for the user’s language preference setting.
        paragraphStyle.baseWritingDirection =  NSWritingDirectionNatural;
    }
    
    if (retAlign) {
        paragraphStyle.alignment = retAlign;
    }
    
    if (_lineHeight) {
        paragraphStyle.maximumLineHeight = _lineHeight;
        paragraphStyle.minimumLineHeight = _lineHeight;
    }
    
    if (_lineHeight || _textAlign) {
        [attributedString addAttribute:NSParagraphStyleAttributeName
                                 value:paragraphStyle
                                 range:(NSRange){0, attributedString.length}];
    }

    return attributedString;
}

- (BOOL)adjustLineHeight
{
    if (WX_SYS_VERSION_LESS_THAN(@"10.0")) {
        return true;
    }
    return ![self useCoreText];
}

- (NSTextStorage *)textStorageWithWidth:(CGFloat)width
{
    if (_textStorage && width == _textStorageWidth) {
        return _textStorage;
    }
    
    NSLayoutManager *layoutManager = [NSLayoutManager new];
    
    // build AttributeString
    NSAttributedString *attributedString = [self buildAttributeString];
    
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
    [textStorage addLayoutManager:layoutManager];
    
    NSTextContainer *textContainer = [NSTextContainer new];
    textContainer.lineFragmentPadding = 0.0;
    
    if ([[_wordWrap lowercaseString] isEqualToString:@"break-word"]) {
        textContainer.lineBreakMode = NSLineBreakByWordWrapping;
    } else if ([[_wordWrap lowercaseString] isEqualToString:@"normal"]){
        textContainer.lineBreakMode = NSLineBreakByClipping;
    } else {
        // set default lineBreakMode
        textContainer.lineBreakMode = NSLineBreakByCharWrapping;
    }
    
    if (_textOverflow && [_textOverflow length] > 0) {
        if ([_textOverflow isEqualToString:@"ellipsis"])
            textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
    }
    textContainer.maximumNumberOfLines = _lines > 0 ? _lines : 0;
    textContainer.size = (CGSize){isnan(width) ? CGFLOAT_MAX : width, CGFLOAT_MAX};

    [layoutManager addTextContainer:textContainer];
    [layoutManager ensureLayoutForTextContainer:textContainer];
    
    _textStorageWidth = width;
    _textStorage = textStorage;
    
    return textStorage;
}

- (void)syncTextStorageForView
{
    CGFloat width = self.calculatedFrame.size.width - (_padding.left + _padding.right);
    NSTextStorage *textStorage = nil;
    if (![self useCoreText]) {
        textStorage = [self textStorageWithWidth:width];
    }
    [self.weexInstance.componentManager  _addUITask:^{
        if ([self isViewLoaded]) {
            if (![self useCoreText]) {
                ((WXTextView *)self.view).textStorage = textStorage;
            }
            [self readyToRender]; // notify super component
            [self setNeedsDisplay];
        }
    }];
}

- (void)_frameDidCalculated:(BOOL)isChanged
{
    [super _frameDidCalculated:isChanged];
    [self syncTextStorageForView];
}

- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles
{
    [super _updateStylesOnComponentThread:styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:isUpdateStyles];
    NSMutableDictionary * newStyles = [styles mutableCopy];
    for (NSString * key in [resetStyles copy]) {
        [newStyles setObject:@"" forKey:key];
    }
    [self fillCSSStyles:newStyles];
    
    [self syncTextStorageForView];
}

- (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes
{
    [super _updateAttributesOnComponentThread:attributes];
    
    [self fillAttributes:attributes];
    
    [self syncTextStorageForView];
}

- (void)drawTextWithContext:(CGContextRef)context bounds:(CGRect)bounds padding:(UIEdgeInsets)padding
{
    if (bounds.size.width <= 0 || bounds.size.height <= 0) {
        return;
    }
    
    if ([self _needsDrawBorder]) {
        [self _drawBorderWithContext:context size:bounds.size];
    } else {
        WXPerformBlockOnMainThread(^{
            [self _resetNativeBorderRadius];
        });
    }
    if (![self useCoreText]) {
        NSLayoutManager *layoutManager = _textStorage.layoutManagers.firstObject;
        NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
        
        CGRect textFrame = UIEdgeInsetsInsetRect(bounds, padding);
        NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
        
        [layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
        [layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
    } else {
        CGRect textFrame = UIEdgeInsetsInsetRect(bounds, padding);
        // sufficient height for text to draw, or frame lines will be empty
        textFrame.size.height = bounds.size.height * 2;
        CGContextSaveGState(context);
        //flip the coordinate system
        CGContextSetTextMatrix(context, CGAffineTransformIdentity);
        CGContextTranslateCTM(context, 0, textFrame.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        
        NSAttributedString * attributedStringCopy = [self ctAttributedString];
        if (!attributedStringCopy) {
            return;
        }
        //add path
        CGPathRef cgPath = CGPathCreateWithRect(textFrame, NULL);
        CTFramesetterRef ctframesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedStringCopy));
        CTFrameRef coreTextFrameRef = CTFramesetterCreateFrame(ctframesetterRef, CFRangeMake(0, attributedStringCopy.length), cgPath, NULL);
        if (NULL == coreTextFrameRef) {
            // try to protect crash from frame is NULL
            CFRelease(ctframesetterRef);
            CGPathRelease(cgPath);
            return;
        }
        CFRelease(ctframesetterRef);
        CFArrayRef ctLines = CTFrameGetLines(coreTextFrameRef);
        CFIndex lineCount = CFArrayGetCount(ctLines);
        NSMutableArray * mutableLines = [NSMutableArray new];
        CGPoint lineOrigins[lineCount];
        NSUInteger rowCount = 0;
        BOOL needTruncation = NO;
        CTLineRef ctTruncatedLine = NULL;
        CTFrameGetLineOrigins(coreTextFrameRef, CFRangeMake(0, 0), lineOrigins);
        
        if (lineCount > 0 && _lineHeight && WX_SYS_VERSION_LESS_THAN(@"10.0")) {
            CGFloat ascent, descent, leading;
            CTLineRef line1 = (CTLineRef)CFArrayGetValueAtIndex(ctLines, 0);
            CTLineGetTypographicBounds(line1, &ascent, &descent, &leading);
            lineOrigins[0].y += (_lineHeight-(leading+ascent+descent))/2;
        }
        
        for (CFIndex lineIndex = 0;(!_lines || _lines > lineIndex) && lineIndex < lineCount; lineIndex ++) {
            CTLineRef lineRef = NULL;
            lineRef = (CTLineRef)CFArrayGetValueAtIndex(ctLines, lineIndex);
            if (!lineRef) {
                break;
            }
            CGPoint lineOrigin = lineOrigins[lineIndex];
            lineOrigin.x += padding.left;
            if(_lineHeight && WX_SYS_VERSION_LESS_THAN(@"10.0")){
                lineOrigin.y = lineOrigins[0].y - padding.top - _lineHeight * lineIndex ;
            }else{
                lineOrigin.y = lineOrigin.y - padding.top ;
            }
            
            CFArrayRef runs = CTLineGetGlyphRuns(lineRef);
            [mutableLines addObject:(__bridge id _Nonnull)(lineRef)];
            // lineIndex base 0
            rowCount = lineIndex + 1;
            if (_lines > 0 && _truncationLine) {
                if (_truncationLine && rowCount > _lines) {
                    needTruncation = YES;
                    do {
                        NSUInteger lastRow = [mutableLines count];
                        if (lastRow < rowCount) {
                           break;
                        }
                        [mutableLines removeLastObject];
                    } while (1);

                }
            }
            if (_lines > 0 && _truncationLine) {
                if (rowCount >= _lines &&!needTruncation && (CTLineGetStringRange(lineRef).length + CTLineGetStringRange(lineRef).location) < attributedStringCopy.length) {
                    needTruncation = YES;
                }
            }
            
            if (needTruncation) {
                CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y);
                ctTruncatedLine = [self buildTruncatedLineWithRuns:runs lines:mutableLines path:cgPath];
                if (ctTruncatedLine) {
                    CFArrayRef truncatedRuns = CTLineGetGlyphRuns(ctTruncatedLine);
                    [self drawTextWithRuns:truncatedRuns context:context lineOrigin:lineOrigin];
                    CFRelease(ctTruncatedLine);
                    ctTruncatedLine = NULL;
                    continue;
                }
            } else {
                [self drawTextWithRuns:runs context:context lineOrigin:lineOrigin];
            }
        }
        
        [mutableLines removeAllObjects];
        CGPathRelease(cgPath);
        CFRelease(coreTextFrameRef);
        CGContextRestoreGState(context);
    }
}

- (void)drawTextWithRuns:(CFArrayRef)runs context:(CGContextRef)context lineOrigin:(CGPoint)lineOrigin
{
    for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runs); runIndex ++) {
        CTRunRef run = NULL;
        run = (CTRunRef)CFArrayGetValueAtIndex(runs, runIndex);
        CFDictionaryRef attr = NULL;
        attr = CTRunGetAttributes(run);
        //To properly draw the glyphs in a run, the fields tx and ty of the CGAffineTransform returned by CTRunGetTextMatrix should be set to the current text position.
        CGAffineTransform transform = CTRunGetTextMatrix(run);
        transform.tx = lineOrigin.x;
        transform.ty = lineOrigin.y;
        CGContextSetTextMatrix(context, transform);
        
        CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y);
        CTRunDraw(run, context, CFRangeMake(0, 0));
        CFIndex glyphCount = CTRunGetGlyphCount(run);
        if (glyphCount <= 0) continue;
        
        long longForStrikethroughStyleAttributeName= (long)CFDictionaryGetValue(attr, (__bridge void *)NSStrikethroughStyleAttributeName);
        NSUnderlineStyle strikethrough = (NSUnderlineStyle)longForStrikethroughStyleAttributeName;
        
        if (strikethrough) {
            // draw strikethrough
            [self drawLineThroughWithRun:runs context:context index:runIndex origin:lineOrigin];
        }
    }
}

- (CTLineRef)buildTruncatedLineWithRuns:(CFArrayRef)runs lines:(NSMutableArray*)mutableLines path:(CGPathRef)cgPath
{
    NSAttributedString * truncationToken = nil;
    CTLineRef ctTruncatedLine = NULL;
    CTLineRef lastLine = (__bridge CTLineRef)(mutableLines.lastObject);
   
    CFArrayRef lastLineRuns = CTLineGetGlyphRuns(lastLine);
    NSUInteger lastLineRunCount = CFArrayGetCount(lastLineRuns);
    
    CTLineRef truncationTokenLine = NULL;
    NSMutableDictionary *attrs = nil;
    if (lastLineRunCount > 0) {
        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, lastLineRunCount - 1);
        attrs = (id)CTRunGetAttributes(run);
        attrs = attrs ? attrs.mutableCopy : [NSMutableDictionary new];
        CTFontRef font = (__bridge CTFontRef)(attrs[(id)kCTFontAttributeName]);
        CGFloat fontSize = font ? CTFontGetSize(font):32 * self.weexInstance.pixelScaleFactor;
        UIFont * uiFont = [UIFont systemFontOfSize:fontSize];
        if (uiFont) {
            font = CTFontCreateWithFontDescriptor((__bridge CTFontDescriptorRef)uiFont.fontDescriptor, uiFont.pointSize, NULL);
        }
        if (font) {
            attrs[(id)kCTFontAttributeName] = (__bridge id)(font);
            uiFont = nil;
            CFRelease(font);
        }
        CGColorRef color = (__bridge CGColorRef)(attrs[(id)kCTForegroundColorAttributeName]);
        if (color && CFGetTypeID(color) == CGColorGetTypeID() && CGColorGetAlpha(color) == 0) {
            [attrs removeObjectForKey:(id)kCTForegroundColorAttributeName];
        }
        
        attrs = attrs?:[NSMutableDictionary new];
        truncationToken = [[NSAttributedString alloc] initWithString:WXTextTruncationToken attributes:attrs];
        truncationTokenLine = CTLineCreateWithAttributedString((CFAttributedStringRef)truncationToken);
    }
    
    if (truncationTokenLine) {
        // default truncationType is kCTLineTruncationEnd
        CTLineTruncationType truncationType = kCTLineTruncationEnd;
        NSAttributedString *attributedString = [self ctAttributedString];
        NSAttributedString * lastLineText = nil;
        NSRange lastLineTextRange = WXNSRangeFromCFRange(CTLineGetStringRange(lastLine));
        NSRange attributeStringRange = NSMakeRange(0, attributedString.string.length);
        NSRange interSectionRange = NSIntersectionRange(lastLineTextRange, attributeStringRange);
        if (!NSEqualRanges(interSectionRange, lastLineTextRange)) {
            // out of bounds
            lastLineTextRange = interSectionRange;
        }
        lastLineText = [attributedString attributedSubstringFromRange: lastLineTextRange];
        if (!lastLineText) {
            lastLineText = attributedString;
        }
        NSMutableAttributedString *mutableLastLineText = lastLineText.mutableCopy;
        [mutableLastLineText appendAttributedString:truncationToken];
        CTLineRef ctLastLineExtend = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)[mutableLastLineText copy]);
        if (ctLastLineExtend) {
            CGRect cgPathRect = CGRectZero;
            CGFloat truncatedWidth = 0;
            if (CGPathIsRect(cgPath, &cgPathRect)) {
                truncatedWidth = cgPathRect.size.width;
            }
            ctTruncatedLine = CTLineCreateTruncatedLine(ctLastLineExtend, truncatedWidth, truncationType, truncationTokenLine);
            CFRelease(ctLastLineExtend);
            ctLastLineExtend = NULL;
            CFRelease(truncationTokenLine);
            truncationTokenLine = NULL;
        }
    }
    
    return ctTruncatedLine;
}

- (void)drawLineThroughWithRun:(CFArrayRef)runs context:(CGContextRef)context index:(CFIndex)runIndex origin:(CGPoint)lineOrigin
{
    CFRetain(runs);
    CGContextRetain(context);
    
    CGContextSaveGState(context);
    CGFloat xHeight = 0, underLinePosition = 0, lineThickness = 0;
    CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, runIndex);
    WXTextGetRunsMaxMetric(runs, &xHeight, &underLinePosition, &lineThickness);
    
    CGPoint strikethroughStart;
    strikethroughStart.x =  lineOrigin.x - underLinePosition;
    strikethroughStart.y = lineOrigin.y + xHeight/2;
    CGPoint runPosition = CGPointZero;
    CTRunGetPositions(run, CFRangeMake(0, 1), &runPosition);
    strikethroughStart.x = lineOrigin.x + runPosition.x;
    CGContextSetLineWidth(context, WXTextDefaultLineThroughWidth);
    double length = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
    CGContextMoveToPoint(context, strikethroughStart.x, strikethroughStart.y);
    CGContextAddLineToPoint(context, strikethroughStart.x + length, strikethroughStart.y);
    CGContextStrokePath(context);
    
    CGContextRestoreGState(context);
    CFRelease(runs);
    CGContextRelease(context);
}

- (CGSize)calculateTextHeightWithWidth:(CGFloat)aWidth
{
    CGFloat totalHeight = 0;
    CGSize suggestSize = CGSizeZero;
    NSAttributedString * attributedStringCpy = [self ctAttributedString];
    if (!attributedStringCpy) {
        return CGSizeZero;
    }
    if (isnan(aWidth)) {
        aWidth = CGFLOAT_MAX;
    }
    aWidth = [attributedStringCpy boundingRectWithSize:CGSizeMake(aWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil].size.width;
    
    /* Must get ceil of aWidth. Or core text may not return correct bounds.
     Maybe aWidth without ceiling triggered some critical conditions. */
    aWidth = ceil(aWidth);
    CTFramesetterRef ctframesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedStringCpy));
    suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(ctframesetterRef, CFRangeMake(0, 0), NULL, CGSizeMake(aWidth, MAXFLOAT), NULL);
    
    if (_lines == 0) {
        // If not line limit use suggestSize directly.
        CFRelease(ctframesetterRef);
        return CGSizeMake(aWidth, suggestSize.height);
    }
    
    CGMutablePathRef path = NULL;
    path = CGPathCreateMutable();
        // sufficient height to draw text
    CGPathAddRect(path, NULL, CGRectMake(0, 0, aWidth, suggestSize.height * 10));
        
    CTFrameRef frameRef = NULL;
    frameRef = CTFramesetterCreateFrame(ctframesetterRef, CFRangeMake(0, attributedStringCpy.length), path, NULL);
    CGPathRelease(path);
    CFRelease(ctframesetterRef);
    
    if (NULL == frameRef) {
        //try to protect unexpected crash.
        return suggestSize;
    }
    
    CFArrayRef lines = CTFrameGetLines(frameRef);
    CFIndex lineCount = CFArrayGetCount(lines);
    CGFloat ascent = 0;
    CGFloat descent = 0;
    CGFloat leading = 0;
    
    // height = ascent + descent + lineCount*leading
    // ignore linespaing
    NSUInteger actualLineCount = 0;
    for (CFIndex lineIndex = 0; (!_lines|| lineIndex < _lines) && lineIndex < lineCount; lineIndex ++)
    {
        CTLineRef lineRef = NULL;
        lineRef = (CTLineRef)CFArrayGetValueAtIndex(lines, lineIndex);
        CTLineGetTypographicBounds(lineRef, &ascent, &descent, &leading);
        totalHeight += ascent + descent;
        actualLineCount ++;
    }
    
    totalHeight = totalHeight + actualLineCount * leading;
    CFRelease(frameRef);
    
    if (WX_SYS_VERSION_LESS_THAN(@"10.0")) {
        // there is something wrong with coreText drawing text height, trying to fix this with more efficent way.
        if(actualLineCount && actualLineCount < lineCount) {
            suggestSize.height = suggestSize.height * actualLineCount / lineCount;
        }
        return CGSizeMake(aWidth, suggestSize.height);
    }
    return CGSizeMake(aWidth, totalHeight);
}

static void WXTextGetRunsMaxMetric(CFArrayRef runs, CGFloat *xHeight, CGFloat *underlinePosition, CGFloat *lineThickness)
{
    CFRetain(runs);
    CGFloat maxXHeight = 0;
    CGFloat maxUnderlinePos = 0;
    CGFloat maxLineThickness = 0;
    for (NSUInteger index = 0, runsCount = CFArrayGetCount(runs); index < runsCount; index ++) {
        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, index);
        CFDictionaryRef attrs = CTRunGetAttributes(run);
        if (attrs) {
            CTFontRef font = (CTFontRef)CFDictionaryGetValue(attrs, kCTFontAttributeName);
            if (font) {
                CGFloat xHeight = CTFontGetXHeight(font);
                if (xHeight > maxXHeight) {
                    maxXHeight = xHeight;
                }
                
                CGFloat underlinePos = CTFontGetUnderlinePosition(font);
                if (underlinePos < maxUnderlinePos) {
                    maxUnderlinePos = underlinePos;
                }
                
                CGFloat lineThickness = CTFontGetUnderlineThickness(font);
                if (lineThickness > maxLineThickness) {
                    maxLineThickness = lineThickness;
                }
            }
        }
    }
    
    if (xHeight) {
        *xHeight = maxXHeight;
    }
    
    if (underlinePosition) {
        *underlinePosition = maxUnderlinePos;
    }
    
    if (lineThickness) {
        *lineThickness = maxLineThickness;
    }
    
    CFRelease(runs);
}
                                                                                                                                       
NS_INLINE NSRange WXNSRangeFromCFRange(CFRange range) {
    return NSMakeRange(range.location, range.length);
}

#ifdef UITEST
- (NSString *)description
{
    return super.description;
}
#endif
 
- (void)_resetCSSNodeStyles:(NSArray *)styles
{
    [super _resetCSSNodeStyles:styles];
    if ([styles containsObject:@"color"]) {
        self.textColor = [UIColor blackColor];
        [self setNeedsRepaint];
    }
    if ([styles containsObject:@"darkThemeColor"]) {
        self.darkThemeTextColor = nil;
        [self setNeedsRepaint];
    }
    if ([styles containsObject:@"fontSize"]) {
        _fontSize = WX_TEXT_FONT_SIZE;
        [self setNeedsRepaint];
        [self setNeedsLayout];
    }
}

@end

