//
//  Datastreams.m
//  Datastreams
//
//  Created by Nicky Romeijn on 16-06-16.
//  Copyright © 2016 Adversitement. All rights reserved.
//

#import "Tagger.h"
#import "Dispatcher.h"

@implementation Tagger

static objectCount = 0;

-(Tagger *) init :(NSString *)appId :(NSString *)endpoint :(NSNumber *)dispatchInterval :(Boolean) forceStartTimer; {
    self = [super init];

    self.funnel = [[NSMutableDictionary alloc] init];
    self.funnel_lock = [[NSLock alloc] init];
    _dispatcher = [[Dispatcher alloc] init :appId];
    _alias = [[NSUUID UUID] UUIDString];
    _identity = @"";

    [self setAppId:appId];
    [self setEndpoint:endpoint];
    [self setDispatchInterval:dispatchInterval];
    NSDictionary *buildInitFunnel = @{
            @"alias" : _alias,
            @"identity": _identity
    };
    [self addToFunnel:@"alias" : buildInitFunnel];
//    if(objectCount == 1 || forceStartTimer == true){
    NSTimer *timer = [NSTimer timerWithTimeInterval:[dispatchInterval floatValue]
                                             target:self
                                           selector:@selector(dispatch:)
                                           userInfo:nil
                                            repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    NSLog(@"Init tagger with timer");
//    } else {
//        NSLog(@"Init tagger");
//    }
    objectCount++;
    return self;
}

-(void) dispatch:(NSTimer *)timer;{
    NSLog(@"Dispatcher has been called");
    //[self.funnel_lock lock];
    if([[self funnel] count] > 0){
        NSLog(@"Dispatcher has dispatched");
        [_dispatcher dispatch :_endpoint :[self funnel]];
    }
//    [self.funnel_lock unlock];
}

-(void) clearFunnel; {
    [self.funnel_lock lock];
    [[self funnel] removeAllObjects];
    [self.funnel_lock unlock];
}

-(void) addToFunnel :(NSString*)funnelKey :(NSDictionary*)funnelData; {
    [self.funnel_lock lock];
    if([[self funnel] objectForKey:funnelKey] == nil){
        [[self funnel] setObject :[[NSMutableArray alloc] init] forKey :funnelKey];
    }
    [[[self funnel] objectForKey:funnelKey] addObject:funnelData];


    int numberOfItems = 0;
    for(id key in [self funnel]){
        numberOfItems += [[[self funnel] objectForKey:key] count];
    }
    //        if(numberOfItems > 1){
    //            NSLog(@"I am bigger than 1 and am starting to dispatch");
    //            [_dispatcher dispatch :_endpoint :_funnel];
    //        }
    NSLog(@"Array Count = %lu && number of items %u", (unsigned long)[[self funnel] count], numberOfItems);
    [self.funnel_lock unlock];

}

-(void)track :(NSString*)eventName; {
    NSLog(@"Track %@", eventName);
    NSDictionary *funnel = @{
            @"event" : eventName,
            @"alias":_alias,
            @"identitiy":_identity,
            @"time":[self getTimestamp]
    };

    [self addToFunnel:eventName :funnel];
}

-(void)trackWithProperties:(NSString*)eventName:(NSString*)propertiesAsJson;
{
    NSLog(@"Track %@:%@", eventName, propertiesAsJson);
    NSDictionary *funnel = @{
            @"event" : eventName,
            @"alias":_alias,
            @"identitiy":_identity,
            @"time":[self getTimestamp],
            @"properties":propertiesAsJson
    };
    [self addToFunnel:eventName :funnel];
}


-(void)createAlias:(NSString*)alias; {
    NSLog(@"Alias %@", alias);
    _alias = alias;
    NSDictionary *funnel = @{
            @"event" : @"alias",
            @"alias":_alias,
            @"identitiy":_identity,
            @"time":[self getTimestamp]
    };
    [self addToFunnel:@"alias" :funnel];
}

-(void)identify:(NSString *)identity; {
    NSLog(@"Identity %@", identity);
    _identity = identity;
    NSDictionary *funnel = @{
            @"event" : @"identity",
            @"alias":_alias,
            @"identitiy":_identity,
            @"time":[self getTimestamp]
    };
    [self addToFunnel:@"identity" :funnel];
}

-(NSNumber*) getTimestamp; {
    NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
    // NSTimeInterval is defined as double
    NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
    return timeStampObj;
}

-(void)timeEventStartWithProperties:(NSString*)eventName:(NSString*)propertiesAsJson;{
    NSLog(@"timeEventStartWithProperties %@:%@", eventName, propertiesAsJson);
    _startTime = [self getTimestamp];
    _timedEvent = eventName;
    _timedEventProperties = propertiesAsJson;
}

-(void)timeEventStart:(NSString*)eventName;{
    NSLog(@"timeEventStart %@", eventName);
    _startTime = [self getTimestamp];
    _timedEvent = eventName;
}


-(void)timeEventStop:(NSString*)eventName;{
    NSLog(@"timeEventStop %@", eventName);
    if([_timedEvent isEqualToString:eventName]){
        if(_timedEventProperties){
            NSDictionary *funnel = @{
                    @"event" : eventName,
                    @"alias":_alias,
                    @"identitiy":_identity,
                    @"timeStart":_startTime,
                    @"timeStop":[self getTimestamp],
                    @"properties":_timedEventProperties
            };
            [self addToFunnel:eventName :funnel];
        } else {
            NSDictionary *funnel = @{
                    @"event" : eventName,
                    @"alias":_alias,
                    @"identitiy":_identity,
                    @"timeStart":_startTime,
                    @"timeStop":[self getTimestamp]
            };
            [self addToFunnel:eventName :funnel];
        }
    }
}

@end



