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

#import <objc/runtime.h>

#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/ref_counted_object.h"

namespace {
// An implementation of EncodedImageBufferInterface that doesn't perform any copies.
class ObjCEncodedImageBuffer : public webrtc::EncodedImageBufferInterface {
 public:
  static rtc::scoped_refptr<ObjCEncodedImageBuffer> Create(NSData *data) {
    return new rtc::RefCountedObject<ObjCEncodedImageBuffer>(data);
  }
  const uint8_t *data() const override { return static_cast<const uint8_t *>(data_.bytes); }
  // TODO(bugs.webrtc.org/9378): delete this non-const data method.
  uint8_t *data() override {
    return const_cast<uint8_t *>(static_cast<const uint8_t *>(data_.bytes));
  }
  size_t size() const override { return data_.length; }

 protected:
  explicit ObjCEncodedImageBuffer(NSData *data) : data_(data) {}
  ~ObjCEncodedImageBuffer() {}

  NSData *data_;
};
}

// A simple wrapper around webrtc::EncodedImageBufferInterface to make it usable with associated
// objects.
@interface RTCWrappedEncodedImageBuffer : NSObject
@property(nonatomic) rtc::scoped_refptr<webrtc::EncodedImageBufferInterface> buffer;
- (instancetype)initWithEncodedImageBuffer:
    (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer;
@end
@implementation RTCWrappedEncodedImageBuffer
@synthesize buffer = _buffer;
- (instancetype)initWithEncodedImageBuffer:
    (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer {
  self = [super init];
  if (self) {
    _buffer = buffer;
  }
  return self;
}
@end

@implementation RTC_OBJC_TYPE (RTCEncodedImage)
(Private)

    - (rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)encodedData {
  RTCWrappedEncodedImageBuffer *wrappedBuffer =
      objc_getAssociatedObject(self, @selector(encodedData));
  return wrappedBuffer.buffer;
}

- (void)setEncodedData:(rtc::scoped_refptr<webrtc::EncodedImageBufferInterface>)buffer {
  return objc_setAssociatedObject(
      self,
      @selector(encodedData),
      [[RTCWrappedEncodedImageBuffer alloc] initWithEncodedImageBuffer:buffer],
      OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (instancetype)initWithNativeEncodedImage:(const webrtc::EncodedImage &)encodedImage {
  if (self = [super init]) {
    // A reference to the encodedData must be stored so that it's kept alive as long
    // self.buffer references its underlying data.
    self.encodedData = encodedImage.GetEncodedData();
    // Wrap the buffer in NSData without copying, do not take ownership.
    self.buffer = [NSData dataWithBytesNoCopy:self.encodedData->data()
                                       length:encodedImage.size()
                                 freeWhenDone:NO];
    self.encodedWidth = rtc::dchecked_cast<int32_t>(encodedImage._encodedWidth);
    self.encodedHeight = rtc::dchecked_cast<int32_t>(encodedImage._encodedHeight);
    self.timeStamp = encodedImage.Timestamp();
    self.captureTimeMs = encodedImage.capture_time_ms_;
    self.ntpTimeMs = encodedImage.ntp_time_ms_;
    self.flags = encodedImage.timing_.flags;
    self.encodeStartMs = encodedImage.timing_.encode_start_ms;
    self.encodeFinishMs = encodedImage.timing_.encode_finish_ms;
    self.frameType = static_cast<RTCFrameType>(encodedImage._frameType);
    self.rotation = static_cast<RTCVideoRotation>(encodedImage.rotation_);
    self.qp = @(encodedImage.qp_);
    self.contentType = (encodedImage.content_type_ == webrtc::VideoContentType::SCREENSHARE) ?
        RTCVideoContentTypeScreenshare :
        RTCVideoContentTypeUnspecified;
  }

  return self;
}

- (webrtc::EncodedImage)nativeEncodedImage {
  // Return the pointer without copying.
  webrtc::EncodedImage encodedImage;
  if (self.encodedData) {
    encodedImage.SetEncodedData(self.encodedData);
  } else if (self.buffer) {
    encodedImage.SetEncodedData(ObjCEncodedImageBuffer::Create(self.buffer));
  }
  encodedImage.set_size(self.buffer.length);
  encodedImage._encodedWidth = rtc::dchecked_cast<uint32_t>(self.encodedWidth);
  encodedImage._encodedHeight = rtc::dchecked_cast<uint32_t>(self.encodedHeight);
  encodedImage.SetTimestamp(self.timeStamp);
  encodedImage.capture_time_ms_ = self.captureTimeMs;
  encodedImage.ntp_time_ms_ = self.ntpTimeMs;
  encodedImage.timing_.flags = self.flags;
  encodedImage.timing_.encode_start_ms = self.encodeStartMs;
  encodedImage.timing_.encode_finish_ms = self.encodeFinishMs;
  encodedImage._frameType = webrtc::VideoFrameType(self.frameType);
  encodedImage.rotation_ = webrtc::VideoRotation(self.rotation);
  encodedImage.qp_ = self.qp ? self.qp.intValue : -1;
  encodedImage.content_type_ = (self.contentType == RTCVideoContentTypeScreenshare) ?
      webrtc::VideoContentType::SCREENSHARE :
      webrtc::VideoContentType::UNSPECIFIED;

  return encodedImage;
}

@end
