/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#import "ARDStatsBuilder.h"

#import <WebRTC/RTCLegacyStatsReport.h>
#import <WebRTC/RTCMacros.h>

#import "ARDBitrateTracker.h"
#import "ARDUtilities.h"

@implementation ARDStatsBuilder {
  // Connection stats.
  NSString *_connRecvBitrate;
  NSString *_connRtt;
  NSString *_connSendBitrate;
  NSString *_localCandType;
  NSString *_remoteCandType;
  NSString *_transportType;

  // BWE stats.
  NSString *_actualEncBitrate;
  NSString *_availableRecvBw;
  NSString *_availableSendBw;
  NSString *_targetEncBitrate;

  // Video send stats.
  NSString *_videoEncodeMs;
  NSString *_videoInputFps;
  NSString *_videoInputHeight;
  NSString *_videoInputWidth;
  NSString *_videoSendCodec;
  NSString *_videoSendBitrate;
  NSString *_videoSendFps;
  NSString *_videoSendHeight;
  NSString *_videoSendWidth;

  // QP stats.
  int _videoQPSum;
  int _framesEncoded;
  int _oldVideoQPSum;
  int _oldFramesEncoded;

  // Video receive stats.
  NSString *_videoDecodeMs;
  NSString *_videoDecodedFps;
  NSString *_videoOutputFps;
  NSString *_videoRecvBitrate;
  NSString *_videoRecvFps;
  NSString *_videoRecvHeight;
  NSString *_videoRecvWidth;

  // Audio send stats.
  NSString *_audioSendBitrate;
  NSString *_audioSendCodec;

  // Audio receive stats.
  NSString *_audioCurrentDelay;
  NSString *_audioExpandRate;
  NSString *_audioRecvBitrate;
  NSString *_audioRecvCodec;

  // Bitrate trackers.
  ARDBitrateTracker *_audioRecvBitrateTracker;
  ARDBitrateTracker *_audioSendBitrateTracker;
  ARDBitrateTracker *_connRecvBitrateTracker;
  ARDBitrateTracker *_connSendBitrateTracker;
  ARDBitrateTracker *_videoRecvBitrateTracker;
  ARDBitrateTracker *_videoSendBitrateTracker;
}

- (instancetype)init {
  if (self = [super init]) {
    _audioSendBitrateTracker = [[ARDBitrateTracker alloc] init];
    _audioRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
    _connSendBitrateTracker = [[ARDBitrateTracker alloc] init];
    _connRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
    _videoSendBitrateTracker = [[ARDBitrateTracker alloc] init];
    _videoRecvBitrateTracker = [[ARDBitrateTracker alloc] init];
    _videoQPSum = 0;
    _framesEncoded = 0;
  }
  return self;
}

- (NSString *)statsString {
  NSMutableString *result = [NSMutableString string];
  NSString *systemStatsFormat = @"(cpu)%ld%%\n";
  [result appendString:[NSString stringWithFormat:systemStatsFormat,
      (long)ARDGetCpuUsagePercentage()]];

  // Connection stats.
  NSString *connStatsFormat = @"CN %@ms | %@->%@/%@ | (s)%@ | (r)%@\n";
  [result appendString:[NSString stringWithFormat:connStatsFormat,
      _connRtt,
      _localCandType, _remoteCandType, _transportType,
      _connSendBitrate, _connRecvBitrate]];

  // Video send stats.
  NSString *videoSendFormat = @"VS (input) %@x%@@%@fps | (sent) %@x%@@%@fps\n"
                               "VS (enc) %@/%@ | (sent) %@/%@ | %@ms | %@\n"
                               "AvgQP (past %d encoded frames) = %d\n ";
  int avgqp = [self calculateAvgQP];

  [result appendString:[NSString stringWithFormat:videoSendFormat,
      _videoInputWidth, _videoInputHeight, _videoInputFps,
      _videoSendWidth, _videoSendHeight, _videoSendFps,
      _actualEncBitrate, _targetEncBitrate,
      _videoSendBitrate, _availableSendBw,
      _videoEncodeMs,
      _videoSendCodec,
      _framesEncoded - _oldFramesEncoded, avgqp]];

  // Video receive stats.
  NSString *videoReceiveFormat =
      @"VR (recv) %@x%@@%@fps | (decoded)%@ | (output)%@fps | %@/%@ | %@ms\n";
  [result appendString:[NSString stringWithFormat:videoReceiveFormat,
      _videoRecvWidth, _videoRecvHeight, _videoRecvFps,
      _videoDecodedFps,
      _videoOutputFps,
      _videoRecvBitrate, _availableRecvBw,
      _videoDecodeMs]];

  // Audio send stats.
  NSString *audioSendFormat = @"AS %@ | %@\n";
  [result appendString:[NSString stringWithFormat:audioSendFormat,
      _audioSendBitrate, _audioSendCodec]];

  // Audio receive stats.
  NSString *audioReceiveFormat = @"AR %@ | %@ | %@ms | (expandrate)%@";
  [result appendString:[NSString stringWithFormat:audioReceiveFormat,
      _audioRecvBitrate, _audioRecvCodec, _audioCurrentDelay,
      _audioExpandRate]];

  return result;
}

- (void)parseStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  NSString *reportType = statsReport.type;
  if ([reportType isEqualToString:@"ssrc"] &&
      [statsReport.reportId rangeOfString:@"ssrc"].location != NSNotFound) {
    if ([statsReport.reportId rangeOfString:@"send"].location != NSNotFound) {
      [self parseSendSsrcStatsReport:statsReport];
    }
    if ([statsReport.reportId rangeOfString:@"recv"].location != NSNotFound) {
      [self parseRecvSsrcStatsReport:statsReport];
    }
  } else if ([reportType isEqualToString:@"VideoBwe"]) {
    [self parseBweStatsReport:statsReport];
  } else if ([reportType isEqualToString:@"googCandidatePair"]) {
    [self parseConnectionStatsReport:statsReport];
  }
}

#pragma mark - Private

- (int)calculateAvgQP {
  int deltaFramesEncoded = _framesEncoded - _oldFramesEncoded;
  int deltaQPSum = _videoQPSum - _oldVideoQPSum;

  return deltaFramesEncoded != 0 ? deltaQPSum / deltaFramesEncoded : 0;
}

- (void)updateBweStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googAvailableSendBandwidth"]) {
    _availableSendBw = [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
  } else if ([key isEqualToString:@"googAvailableReceiveBandwidth"]) {
    _availableRecvBw = [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
  } else if ([key isEqualToString:@"googActualEncBitrate"]) {
    _actualEncBitrate = [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
  } else if ([key isEqualToString:@"googTargetEncBitrate"]) {
    _targetEncBitrate = [ARDBitrateTracker bitrateStringForBitrate:value.doubleValue];
  }
}

- (void)parseBweStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateBweStatOfKey:key value:value];
      }];
}

- (void)updateConnectionStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googRtt"]) {
    _connRtt = value;
  } else if ([key isEqualToString:@"googLocalCandidateType"]) {
    _localCandType = value;
  } else if ([key isEqualToString:@"googRemoteCandidateType"]) {
    _remoteCandType = value;
  } else if ([key isEqualToString:@"googTransportType"]) {
    _transportType = value;
  } else if ([key isEqualToString:@"bytesReceived"]) {
    NSInteger byteCount = value.integerValue;
    [_connRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _connRecvBitrate = _connRecvBitrateTracker.bitrateString;
  } else if ([key isEqualToString:@"bytesSent"]) {
    NSInteger byteCount = value.integerValue;
    [_connSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _connSendBitrate = _connSendBitrateTracker.bitrateString;
  }
}

- (void)parseConnectionStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  NSString *activeConnection = statsReport.values[@"googActiveConnection"];
  if (![activeConnection isEqualToString:@"true"]) {
    return;
  }
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateConnectionStatOfKey:key value:value];
      }];
}

- (void)parseSendSsrcStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  NSDictionary *values = statsReport.values;
  if ([values objectForKey:@"googFrameRateSent"]) {
    // Video track.
    [self parseVideoSendStatsReport:statsReport];
  } else if ([values objectForKey:@"audioInputLevel"]) {
    // Audio track.
    [self parseAudioSendStatsReport:statsReport];
  }
}

- (void)updateAudioSendStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googCodecName"]) {
    _audioSendCodec = value;
  } else if ([key isEqualToString:@"bytesSent"]) {
    NSInteger byteCount = value.integerValue;
    [_audioSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _audioSendBitrate = _audioSendBitrateTracker.bitrateString;
  }
}

- (void)parseAudioSendStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateAudioSendStatOfKey:key value:value];
      }];
}

- (void)updateVideoSendStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googCodecName"]) {
    _videoSendCodec = value;
  } else if ([key isEqualToString:@"googFrameHeightInput"]) {
    _videoInputHeight = value;
  } else if ([key isEqualToString:@"googFrameWidthInput"]) {
    _videoInputWidth = value;
  } else if ([key isEqualToString:@"googFrameRateInput"]) {
    _videoInputFps = value;
  } else if ([key isEqualToString:@"googFrameHeightSent"]) {
    _videoSendHeight = value;
  } else if ([key isEqualToString:@"googFrameWidthSent"]) {
    _videoSendWidth = value;
  } else if ([key isEqualToString:@"googFrameRateSent"]) {
    _videoSendFps = value;
  } else if ([key isEqualToString:@"googAvgEncodeMs"]) {
    _videoEncodeMs = value;
  } else if ([key isEqualToString:@"bytesSent"]) {
    NSInteger byteCount = value.integerValue;
    [_videoSendBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _videoSendBitrate = _videoSendBitrateTracker.bitrateString;
  } else if ([key isEqualToString:@"qpSum"]) {
    _oldVideoQPSum = _videoQPSum;
    _videoQPSum = value.integerValue;
  } else if ([key isEqualToString:@"framesEncoded"]) {
    _oldFramesEncoded = _framesEncoded;
    _framesEncoded = value.integerValue;
  }
}

- (void)parseVideoSendStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateVideoSendStatOfKey:key value:value];
      }];
}

- (void)parseRecvSsrcStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  NSDictionary *values = statsReport.values;
  if ([values objectForKey:@"googFrameWidthReceived"]) {
    // Video track.
    [self parseVideoRecvStatsReport:statsReport];
  } else if ([values objectForKey:@"audioOutputLevel"]) {
    // Audio track.
    [self parseAudioRecvStatsReport:statsReport];
  }
}

- (void)updateAudioRecvStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googCodecName"]) {
    _audioRecvCodec = value;
  } else if ([key isEqualToString:@"bytesReceived"]) {
    NSInteger byteCount = value.integerValue;
    [_audioRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _audioRecvBitrate = _audioRecvBitrateTracker.bitrateString;
  } else if ([key isEqualToString:@"googSpeechExpandRate"]) {
    _audioExpandRate = value;
  } else if ([key isEqualToString:@"googCurrentDelayMs"]) {
    _audioCurrentDelay = value;
  }
}

- (void)parseAudioRecvStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateAudioRecvStatOfKey:key value:value];
      }];
}

- (void)updateVideoRecvStatOfKey:(NSString *)key value:(NSString *)value {
  if ([key isEqualToString:@"googFrameHeightReceived"]) {
    _videoRecvHeight = value;
  } else if ([key isEqualToString:@"googFrameWidthReceived"]) {
    _videoRecvWidth = value;
  } else if ([key isEqualToString:@"googFrameRateReceived"]) {
    _videoRecvFps = value;
  } else if ([key isEqualToString:@"googFrameRateDecoded"]) {
    _videoDecodedFps = value;
  } else if ([key isEqualToString:@"googFrameRateOutput"]) {
    _videoOutputFps = value;
  } else if ([key isEqualToString:@"googDecodeMs"]) {
    _videoDecodeMs = value;
  } else if ([key isEqualToString:@"bytesReceived"]) {
    NSInteger byteCount = value.integerValue;
    [_videoRecvBitrateTracker updateBitrateWithCurrentByteCount:byteCount];
    _videoRecvBitrate = _videoRecvBitrateTracker.bitrateString;
  }
}

- (void)parseVideoRecvStatsReport:(RTC_OBJC_TYPE(RTCLegacyStatsReport) *)statsReport {
  [statsReport.values
      enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
        [self updateVideoRecvStatOfKey:key value:value];
      }];
}

@end

