// Copyright © 2022 BytePlusRTC All rights reserved.
// SPDX-License-Identifier: MIT

//
//  VertcVod.m
//  

#import "VertcVod.h"
#import "TTSDKFramework/TTSDKPlayer.h"
#import "VodAudioProcessor.h"
#import "VodVideoProcessor.h"

@interface VertcVod ()

@property (nonatomic, strong) NSDictionary *options;
@property (nonatomic, strong) ByteRTCVideo *rtcEngine;
@property (nonatomic, strong) TTVideoEngine *videoEngine;
@property (nonatomic, strong) VodAudioProcessor *audioProcesser;
@property (nonatomic, strong) VodVideoProcessor *videoProcesser;

@end

@implementation VertcVod {
    EngineAudioWrapper ttAudioWrapper;
    EngineVideoWrapper ttVideoWrapper;
}

- (void)dealloc {
    NSLog(@"FeedSharePlayerComponentDealloc-%@-%@-%@", self.videoEngine, ttAudioWrapper.context, ttVideoWrapper.context);
    if (self.videoEngine) {
        NSLog(@"dealloc videoEngineg");
    }
    
    self.videoEngine = nil;
    self.rtcEngine = nil;
    ttAudioWrapper.context = NULL;
    ttVideoWrapper.context = NULL;
}

- (void)stop {
}


- (int) startVodPlayerCapture:(ByteRTCVideo *)rtc player:(id)player options:(NSDictionary *)options;
{
    TTVideoEngine *videoEngine = [self getVidoeEngine:player];
    
    if (videoEngine == nil) {
        @throw [NSException exceptionWithName:@"unknown videoEngine" reason:@"can't get player" userInfo:@{}];
    }
    
    self.rtcEngine = rtc;
    self.options = options;
    self.videoEngine = videoEngine;
    self.audioProcesser = [[VodAudioProcessor alloc] initWithRTCKit:rtc options:options];
    self.videoProcesser = [[VodVideoProcessor alloc] initWithRTCKit:rtc options:options];
    
    [rtc setVideoSourceType:ByteRTCVideoSourceTypeExternal WithStreamIndex:ByteRTCStreamIndexScreen];
    [rtc setScreenAudioSourceType:ByteRTCAudioSourceTypeExternal];
    
    ttAudioWrapper.open = openAudio;
    ttAudioWrapper.process = processAudio;
    ttAudioWrapper.close = closeAudio;
    ttAudioWrapper.release = releaseAudio;
    ttAudioWrapper.context = (__bridge void *)_audioProcesser;
    [videoEngine setAudioProcessor:&ttAudioWrapper];
       
    ttVideoWrapper.process = videoProcessFunc;
    ttVideoWrapper.release = videoReleaseFunc;
    ttVideoWrapper.context = (__bridge void *)_videoProcesser;
    [videoEngine setVideoWrapper:&ttVideoWrapper];
    
    return 0;
}

- (int) stopVodPlayerCapture:(ByteRTCVideo *)rtc;
{
    [self.videoEngine setAudioProcessor:NULL];
    self.audioProcesser = nil;
    self.videoProcesser = nil;
    ttAudioWrapper.context = NULL;
    ttVideoWrapper.context = NULL;
    [rtc setVideoSourceType:ByteRTCVideoSourceTypeInternal WithStreamIndex:ByteRTCStreamIndexScreen];
    [rtc setScreenAudioSourceType:ByteRTCAudioSourceTypeInternal];
    self.options = nil;
    self.rtcEngine = nil;
    self.videoEngine = nil;
    return 0;
}

- (TTVideoEngine *) getVidoeEngine:(id)arg
{
    if ([arg isKindOfClass:[TTVideoEngine class]]) {
        return arg;
    }

    return nil;
}


#pragma mark - playerAudio

static void openAudio (void *context, int samplerate, int channels, int duration) {
    VodAudioProcessor *process = (__bridge VodAudioProcessor *)(context);
    [process openAudio:samplerate channels:channels];
}

static void processAudio (void *context, float **inouts, int samples, int64_t timestamp) {
    VodAudioProcessor *process = (__bridge VodAudioProcessor *)(context);
    [process processAudio:inouts samples:samples timestamp:timestamp];
}

static void closeAudio (void *context) {
    VodAudioProcessor *process = (__bridge VodAudioProcessor *)(context);
    [process closeAudio];
}

static void releaseAudio (void *context) {
    VodAudioProcessor *process = (__bridge VodAudioProcessor *)(context);
    [process releaseAudio];
}


#pragma mark - Player Video
static void videoProcessFunc(void *context, CVPixelBufferRef frame, int64_t timestamp) {
    VodVideoProcessor *process = (__bridge VodVideoProcessor *)(context);
    [process processVideo:frame timestamp:timestamp];
}

static void videoReleaseFunc(void *context) {
    VodVideoProcessor *process = (__bridge VodVideoProcessor *)(context);
    [process releaseVideo];
}

@end
