/*
 *  Copyright 2019 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 "RTCStatisticsReport+Private.h"

#include "helpers/NSString+StdString.h"
#include "rtc_base/checks.h"

namespace webrtc {

/** Converts a single value to a suitable NSNumber, NSString or NSArray
   containing NSNumbers or NSStrings, or NSDictionary of NSString keys to
   NSNumber values.*/
NSObject *ValueFromStatsAttribute(const Attribute &attribute) {
  if (!attribute.has_value()) {
    return nil;
  }
  if (attribute.holds_alternative<bool>()) {
    return [NSNumber numberWithBool:attribute.get<bool>()];
  } else if (attribute.holds_alternative<int32_t>()) {
    return [NSNumber numberWithInt:attribute.get<int32_t>()];
  } else if (attribute.holds_alternative<uint32_t>()) {
    return [NSNumber numberWithUnsignedInt:attribute.get<uint32_t>()];
  } else if (attribute.holds_alternative<int64_t>()) {
    return [NSNumber numberWithLong:attribute.get<int64_t>()];
  } else if (attribute.holds_alternative<uint64_t>()) {
    return [NSNumber numberWithUnsignedLong:attribute.get<uint64_t>()];
  } else if (attribute.holds_alternative<double>()) {
    return [NSNumber numberWithDouble:attribute.get<double>()];
  } else if (attribute.holds_alternative<std::string>()) {
    return [NSString stringForStdString:attribute.get<std::string>()];
  } else if (attribute.holds_alternative<std::vector<bool>>()) {
    std::vector<bool> sequence = attribute.get<std::vector<bool>>();
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:sequence.size()];
    for (auto item : sequence) {
      [array addObject:[NSNumber numberWithBool:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<int32_t>>()) {
    std::vector<int32_t> sequence = attribute.get<std::vector<int32_t>>();
    NSMutableArray<NSNumber *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSNumber numberWithInt:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<uint32_t>>()) {
    std::vector<uint32_t> sequence = attribute.get<std::vector<uint32_t>>();
    NSMutableArray<NSNumber *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSNumber numberWithUnsignedInt:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<int64_t>>()) {
    std::vector<int64_t> sequence = attribute.get<std::vector<int64_t>>();
    NSMutableArray<NSNumber *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSNumber numberWithLong:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<uint64_t>>()) {
    std::vector<uint64_t> sequence = attribute.get<std::vector<uint64_t>>();
    NSMutableArray<NSNumber *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSNumber numberWithUnsignedLong:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<double>>()) {
    std::vector<double> sequence = attribute.get<std::vector<double>>();
    NSMutableArray<NSNumber *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSNumber numberWithDouble:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::vector<std::string>>()) {
    std::vector<std::string> sequence =
        attribute.get<std::vector<std::string>>();
    NSMutableArray<NSString *> *array =
        [NSMutableArray arrayWithCapacity:sequence.size()];
    for (const auto &item : sequence) {
      [array addObject:[NSString stringForStdString:item]];
    }
    return [array copy];
  } else if (attribute.holds_alternative<std::map<std::string, uint64_t>>()) {
    std::map<std::string, uint64_t> map =
        attribute.get<std::map<std::string, uint64_t>>();
    NSMutableDictionary<NSString *, NSNumber *> *dictionary =
        [NSMutableDictionary dictionaryWithCapacity:map.size()];
    for (const auto &item : map) {
      dictionary[[NSString stringForStdString:item.first]] = @(item.second);
    }
    return [dictionary copy];
  } else if (attribute.holds_alternative<std::map<std::string, double>>()) {
    std::map<std::string, double> map =
        attribute.get<std::map<std::string, double>>();
    NSMutableDictionary<NSString *, NSNumber *> *dictionary =
        [NSMutableDictionary dictionaryWithCapacity:map.size()];
    for (const auto &item : map) {
      dictionary[[NSString stringForStdString:item.first]] = @(item.second);
    }
    return [dictionary copy];
  }
  RTC_DCHECK_NOTREACHED();
  return nil;
}
}  // namespace webrtc

@implementation RTC_OBJC_TYPE (RTCStatistics)

@synthesize id = _id;
@synthesize timestamp_us = _timestamp_us;
@synthesize type = _type;
@synthesize values = _values;

- (instancetype)initWithStatistics:(const webrtc::RTCStats &)statistics {
  self = [super init];
  if (self) {
    _id = [NSString stringForStdString:statistics.id()];
    _timestamp_us = statistics.timestamp().us();
    _type = [NSString stringWithCString:statistics.type()
                               encoding:NSUTF8StringEncoding];

    const std::vector<webrtc::Attribute> attributes = statistics.Attributes();
    NSMutableDictionary<NSString *, NSObject *> *values =
        [NSMutableDictionary dictionaryWithCapacity:attributes.size()];
    for (const auto &attribute : attributes) {
      NSObject *value = ValueFromStatsAttribute(attribute);
      if (value) {
        NSString *name = [NSString stringWithCString:attribute.name()
                                            encoding:NSUTF8StringEncoding];
        RTC_DCHECK(name.length > 0);
        RTC_DCHECK(!values[name]);
        values[name] = value;
      }
    }
    _values = [values copy];
  }

  return self;
}

- (NSString *)description {
  return [NSString
      stringWithFormat:@"id = %@, type = %@, timestamp = %.0f, values = %@",
                       self.id,
                       self.type,
                       self.timestamp_us,
                       self.values];
}

@end

@implementation RTC_OBJC_TYPE (RTCStatisticsReport)

@synthesize timestamp_us = _timestamp_us;
@synthesize statistics = _statistics;

- (NSString *)description {
  return [NSString stringWithFormat:@"timestamp = %.0f, statistics = %@",
                                    self.timestamp_us,
                                    self.statistics];
}

@end

@implementation RTC_OBJC_TYPE (RTCStatisticsReport)
(Private)

    - (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report {
  self = [super init];
  if (self) {
    _timestamp_us = report.timestamp().us();

    NSMutableDictionary *statisticsById =
        [NSMutableDictionary dictionaryWithCapacity:report.size()];
    for (const auto &stat : report) {
      RTC_OBJC_TYPE(RTCStatistics) *statistics =
          [[RTC_OBJC_TYPE(RTCStatistics) alloc] initWithStatistics:stat];
      statisticsById[statistics.id] = statistics;
    }
    _statistics = [statisticsById copy];
  }

  return self;
}

@end
