#import <Foundation/Foundation.h>
#import <React/RCTLog.h>
#import "RNFileCacheStat.h"

@implementation RNFileCacheStat {
  NSMutableArray *downloadStats;
  NSMutableDictionary *downloadQueue;
}

- (id)init
{
  if(self = [super init]) {
    downloadStats = [[NSMutableArray alloc] init];
    downloadQueue = [[NSMutableDictionary alloc] init];
  }
  return self;
}

- (double)bpsFrom:(double)from to:(double)to
{
  // invalid
  if(from >= to) return 0.0;

  double bytes = 0;

  @synchronized(downloadStats) {
    for(id stat in downloadStats) {
      double startTime = [[stat objectForKey:@"startTime"] doubleValue];
      double endTime = [[stat objectForKey:@"endTime"] doubleValue];
      double length = [[stat objectForKey:@"length"] doubleValue];

      // not within from-to
      if(endTime <= from || to <= startTime) continue;

      double elapsed = endTime - startTime;

      if(elapsed == 0) continue;

      double sub = MIN(to, endTime) - MAX(from, startTime);
      bytes += length * MIN(sub, elapsed)/elapsed;
    }
  }

  return 8000.0 * bytes/(to-from);
}

- (void)start: (NSUInteger)taskId
{
  @synchronized(downloadQueue) {
    double now = 1000.0 * [[NSDate date] timeIntervalSince1970];
    NSNumber *startTime = [NSNumber numberWithDouble: now];
    [downloadQueue setObject:startTime
                      forKey: [NSNumber numberWithUnsignedLong: taskId]];
  }
}

- (void)end: (NSUInteger)taskId withData:(NSData *)data
{
  NSNumber *startTime;
  @synchronized(downloadQueue) {
    startTime = [downloadQueue objectForKey: [NSNumber numberWithUnsignedLong: taskId]];
    [downloadQueue removeObjectForKey: [NSNumber numberWithUnsignedLong: taskId]];
  }
  if(!startTime) return;
  double now = 1000.0 * [[NSDate date] timeIntervalSince1970];
  NSNumber *endTime = [NSNumber numberWithDouble: now];
  @synchronized(downloadStats) {
    [downloadStats addObject:@{
                @"startTime": startTime,
                  @"endTime": endTime,
                   @"length": [NSNumber numberWithUnsignedLong: data.length]
    }];
  }
}

@end
