/*
 *  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 "sdk/objc/api/peerconnection/RTCLegacyStatsReport.h"
#import "sdk/objc/base/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

