/*
 * 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 "WXTimerModule.h"
#import "WXSDKManager.h"
#import "WXLog.h"
#import "WXAssert.h"
#import "WXMonitor.h"
#import "WXSDKInstance_performance.h"
#import "WXSDKError.h"
#import "WXExceptionUtils.h"

@interface WXTimerTarget : NSObject

- (instancetype)initWithCallback:(NSString *)callbackID shouldRepeat:(BOOL)shouldRepeat weexInstance:(WXSDKInstance *)weexInstance;

@end

@implementation WXTimerTarget
{
    NSString * _callbackID;
    __weak WXSDKInstance *_weexInstance;
    BOOL _shouldRepeat;
}

- (instancetype)initWithCallback:(NSString *)callbackID shouldRepeat:(BOOL)shouldRepeat weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super init]) {
        _callbackID = callbackID;
        _weexInstance = weexInstance;
        _shouldRepeat = shouldRepeat;
        
        if (weexInstance && !weexInstance.isJSCreateFinish) {
            weexInstance.performance.timerNum++;
            [weexInstance.apmInstance updateFSDiffStats:KEY_PAGE_STATS_FS_TIMER_NUM withDiffValue:1];
        }
    }
    
    return self;
}

- (void)trigger
{
    [[WXSDKManager bridgeMgr] callBack:_weexInstance.instanceId funcId:_callbackID params:nil keepAlive:_shouldRepeat];
}

+ (void) checkExcuteInBack:(NSString*) instanceId
{
    //todo,if instance is nil or instance has detroy ,can't record timer in back.....
    WXSDKInstance* instance = [WXSDKManager instanceForID:instanceId];
    if (nil == instance) {
        return;
    }
    if (instance.state == WeexInstanceBackground || instance.state == WeexInstanceDisappear
        || instance.state == WeexInstanceDestroy) {
        [instance.apmInstance updateDiffStats:KEY_PAGE_TIMER_BACK_NUM withDiffValue:1];
    }
}

@end

@implementation WXTimerModule
{
    BOOL _timeoutNANReported;
    BOOL _timeoutRepeatReported;
    NSMutableDictionary *_timers;
}

@synthesize weexInstance;

WX_EXPORT_METHOD(@selector(setTimeout:time:))
WX_EXPORT_METHOD(@selector(clearTimeout:))
WX_EXPORT_METHOD(@selector(setInterval:time:))
WX_EXPORT_METHOD(@selector(clearInterval:))

- (instancetype)init
{
    if (self = [super init]) {
        _timers = [NSMutableDictionary dictionary];
    }
    
    return self;
}

- (void)createTimerWithCallback:(NSString *)callbackID time:(NSTimeInterval)milliseconds shouldRepeat:(BOOL)shouldRepeat
{
    WXAssert(callbackID, @"callbackID for timer must not be nil.");
    
    if (milliseconds == 0 && !shouldRepeat) {
        [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callbackID params:nil keepAlive:NO];
    }
    
    WXTimerTarget *target = [[WXTimerTarget alloc] initWithCallback:callbackID shouldRepeat:shouldRepeat weexInstance:self.weexInstance];
    
    [self createTimerWithCallback:callbackID time:milliseconds target:target selector:@selector(trigger) shouldRepeat:shouldRepeat];
}

# pragma mark Timer API

- (void)setTimeout:(NSString *)callbackID time:(NSTimeInterval)time
{
    [self createTimerWithCallback:callbackID time:time shouldRepeat:NO];
}

- (void)setInterval:(NSString *)callbackID time:(NSTimeInterval)time
{
    [self createTimerWithCallback:callbackID time:time shouldRepeat:YES];
}

- (void)clearTimeout:(NSString *)callbackID
{
    if (!callbackID) {
        WXLogError(@"no callbackID for clearTimeout/clearInterval");
        return;
    }
    
    NSTimer *timer = _timers[callbackID];
    if (!timer) {
        WXLogWarning(@"no timer found for callbackID:%@", callbackID);
        return;
    }

    [timer invalidate];
    [_timers removeObjectForKey:callbackID];
}

- (void)clearInterval:(NSString *)callbackID
{
    [self clearTimeout:callbackID];
}

- (void)dealloc
{
    if (_timers) {
        for (NSString *callbackID in _timers) {
            NSTimer *timer = _timers[callbackID];
            [timer invalidate];
        }
        if([_timers count]>0){
             [_timers removeAllObjects];
        }
        _timers = nil;
    }
}

# pragma mark Unit Test

- (void)createTimerWithCallback:(NSString *)callbackID time:(NSTimeInterval)milliseconds target:(id)target selector:(SEL)selector shouldRepeat:(BOOL)shouldRepeat {
    
    WXAssert(!isnan(milliseconds), @"Timer interval is NAN.");
    if (isnan(milliseconds)) { //!OCLint
        WXLogError(@"Create timer with NAN interval.");
        
        if (!_timeoutNANReported) {
            [WXExceptionUtils commitCriticalExceptionRT:self.weexInstance.instanceId errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_JS_TIMER_TIMEOUT_NAN] function:@"" exception:@"Time out is NAN." extParams:nil];
            _timeoutNANReported = YES;
        }
        
        if (shouldRepeat) {
            /* NAN for repeatable timer, we ignore.
             For iOS, scheduledTimerWithTimeInterval with NAN and repeate as YES would crash. */
        }
        else {
            [[WXSDKManager bridgeMgr] callBack:self.weexInstance.instanceId funcId:callbackID params:nil keepAlive:NO];
        }
        return;
    }
    
    if (milliseconds < 100 && shouldRepeat) {
        if (!_timeoutRepeatReported) {
            [WXExceptionUtils commitCriticalExceptionRT:self.weexInstance.instanceId errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_JS_TIMER_REPEAT_HIGH_FREQUENCY] function:@"" exception:[NSString stringWithFormat:@"Repeated timer's timeout value too short. %fms", milliseconds] extParams:nil];
            _timeoutRepeatReported = YES;
        }
    }
    
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:milliseconds/1000.0f target:target selector:selector userInfo:nil repeats:shouldRepeat];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    
    if (!_timers[callbackID]) {
        _timers[callbackID] = timer;
        
        if ([_timers count] > 30) {
            // remove invalid timers
            NSMutableArray* invalidTimerIds = [[NSMutableArray alloc] init];
            for (NSString *cbId in _timers) {
                NSTimer *timer = _timers[cbId];
                if (![timer isValid]) {
                    [invalidTimerIds addObject:cbId];
                }
            }
            [_timers removeObjectsForKeys:invalidTimerIds];
        }
    }
}

- (NSMutableDictionary *)timers
{
    return _timers;
}

@end
