//
// © 2018-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

#import "IoTPlayerState.h"
#import "IoTGlobals.h"
#import "IoTResourceAttributes.h"
#import "IoTMultichannelState.h"

#define GETTER_SYNCHRONIZED(type,property) \
- (type)property \
{ \
dispatch_assert_queue_not(self.syncQueue); \
__block type ret; \
dispatch_sync(self.syncQueue, ^{ \
ret = self->_##property; \
}); \
return ret; \
}

#define SETTER_SYNCHRONIZED(type,method,property,assigner) \
- (void)method:(type)property \
{ \
makeWeak(self) \
dispatch_barrier_async(self.syncQueue, ^{ \
makeStrongAndReturnIfNil(self) \
self->_##property = assigner; \
}); \
}

@interface IoTPlaylistState()

@property (nonatomic,strong, readonly) dispatch_queue_t syncQueue;

@end

@implementation IoTPlaylistState {
    BOOL _playlistSupported;
    NSString *_snapshotID;
    NSString *_userData;
    NSString *_ownerInfo;
    uint _size;
}

- (instancetype)initWithStateSyncQueue:(dispatch_queue_t)syncQueue
{
    self = [super init];
    if (self) {
        self->_syncQueue = syncQueue;
        self->_playlistSupported = NO;
        self->_snapshotID = @"";
        self->_userData = @"";
        self->_ownerInfo = @"";
        self->_size = 0;
    }
    return self;
}

GETTER_SYNCHRONIZED(BOOL,playlistSupported)
GETTER_SYNCHRONIZED(NSString *, snapshotID)
GETTER_SYNCHRONIZED(NSString *, userData)
GETTER_SYNCHRONIZED(NSString *, ownerInfo)
GETTER_SYNCHRONIZED(uint, size)

SETTER_SYNCHRONIZED(BOOL,setPlaylistSupported,playlistSupported,playlistSupported)
SETTER_SYNCHRONIZED(NSString *,setSnapshotID,snapshotID,[snapshotID copy])
SETTER_SYNCHRONIZED(NSString *,setUserData,userData,[userData copy])
SETTER_SYNCHRONIZED(NSString *,setOwnerInfo,ownerInfo,[ownerInfo copy])
SETTER_SYNCHRONIZED(uint,setSize,size,size)

@end

@interface IoTAudioAdjustmentState()

@property (nonatomic,strong, readonly) dispatch_queue_t syncQueue;

@end

@implementation IoTAudioAdjustmentState {
    IoTAudioEffectsAttr *_audioEffectsAttr;
    IoTBassboostAttr *_bassboostAttr;
    IoTPresetReverbAttr *_reverbAttr;
    IoTEqualizerAttr *_equalizerAttr;
    IoTDolbyAttr *_dolbyAttr;
    IoTVirtualXSoundXAttr *_virtualXAttr;
    IoTEffectsTrumpetAttr *_trumpetAttr;
    IoTMeloDAttr *_meloDAttr;
}

- (instancetype)initWithStateSyncQueue:(dispatch_queue_t)syncQueue
{
    self = [super init];
    if (self) {
        self->_syncQueue = syncQueue;
        self->_audioEffectsAttr = nil;
        self->_bassboostAttr = nil;
        self->_reverbAttr = nil;
        self->_equalizerAttr = nil;
        self->_dolbyAttr = nil;
        self->_virtualXAttr = nil;
        self->_trumpetAttr = nil;
        self->_meloDAttr = nil;
    }
    return self;
}

GETTER_SYNCHRONIZED(IoTAudioEffectsAttr *, audioEffectsAttr)
GETTER_SYNCHRONIZED(IoTBassboostAttr *, bassboostAttr)
GETTER_SYNCHRONIZED(IoTPresetReverbAttr *, reverbAttr)
GETTER_SYNCHRONIZED(IoTEqualizerAttr *, equalizerAttr)
GETTER_SYNCHRONIZED(IoTDolbyAttr *, dolbyAttr)
GETTER_SYNCHRONIZED(IoTVirtualXSoundXAttr *, virtualXAttr)
GETTER_SYNCHRONIZED(IoTEffectsTrumpetAttr *, trumpetAttr)
GETTER_SYNCHRONIZED(IoTMeloDAttr *, meloDAttr)

SETTER_SYNCHRONIZED(IoTAudioEffectsAttr *,setAudioEffectsAttr,audioEffectsAttr,audioEffectsAttr)
SETTER_SYNCHRONIZED(IoTBassboostAttr *,setBassboostAttr,bassboostAttr,bassboostAttr)
SETTER_SYNCHRONIZED(IoTPresetReverbAttr *,setReverbAttr,reverbAttr,reverbAttr)
SETTER_SYNCHRONIZED(IoTEqualizerAttr *,setEqualizerAttr,equalizerAttr,equalizerAttr)
SETTER_SYNCHRONIZED(IoTDolbyAttr *,setDolbyAttr,dolbyAttr,dolbyAttr)
SETTER_SYNCHRONIZED(IoTVirtualXSoundXAttr *,setVirtualXAttr,virtualXAttr,virtualXAttr)
SETTER_SYNCHRONIZED(IoTEffectsTrumpetAttr *,setTrumpetAttr,trumpetAttr,trumpetAttr)
SETTER_SYNCHRONIZED(IoTMeloDAttr *, setMeloDAttr,meloDAttr,meloDAttr)

@end


@interface IoTPlayerState()

@property (nonatomic, strong, readonly) dispatch_queue_t syncQueue;

@end

@implementation IoTPlayerState {
    IoTMediaPlayerAttr *_mediaPlayerAttr;
    IoTAudioAdjustmentState *_audioAdjustmentState;
	IoTVolumeControlAttr *_volumeControlAttr;
    IoTVolumeControlAttr *_groupVolumeControlAttr;
    IoTInputSelectorAttr *_inputSelectorAttr;
    IoTOutputSelectorAttr *_outputSelectorAttr;
    IoTGroupAttr *_groupAttr;
    IoTMultichannelGroupSatelliteAttr *_multiChannelGroupSatelliteAttr;
    IoTPlaylistState *_playlistState;
}

- (instancetype)initWithStateSyncQueue:(dispatch_queue_t)syncQueue
{
    self = [super init];
    if (self) {
        self->_syncQueue = syncQueue;
        self->_mediaPlayerAttr = [[IoTMediaPlayerAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_audioAdjustmentState = [[IoTAudioAdjustmentState alloc] initWithStateSyncQueue:syncQueue];
        self->_volumeControlAttr = [[IoTVolumeControlAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_groupVolumeControlAttr = [[IoTVolumeControlAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_inputSelectorAttr = [[IoTInputSelectorAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_outputSelectorAttr = [[IoTOutputSelectorAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_groupAttr = [[IoTGroupAttr alloc] initWithStateSyncQueue:syncQueue];
        self->_multiChannelState = [[IoTMultichannelState alloc] initWithStateSyncQueue:syncQueue];
        self->_playlistState = [[IoTPlaylistState alloc] initWithStateSyncQueue:syncQueue];
    }
    return self;
}

GETTER_SYNCHRONIZED(IoTMediaPlayerAttr *,mediaPlayerAttr)
GETTER_SYNCHRONIZED(IoTAudioAdjustmentState *, audioAdjustmentState)
GETTER_SYNCHRONIZED(IoTVolumeControlAttr *,volumeControlAttr)
GETTER_SYNCHRONIZED(IoTVolumeControlAttr *,groupVolumeControlAttr)
GETTER_SYNCHRONIZED(IoTInputSelectorAttr *,inputSelectorAttr)
GETTER_SYNCHRONIZED(IoTOutputSelectorAttr *,outputSelectorAttr)
GETTER_SYNCHRONIZED(IoTGroupAttr *,groupAttr)
GETTER_SYNCHRONIZED(IoTPlaylistState *,playlistState)

SETTER_SYNCHRONIZED(IoTAudioAdjustmentState *, setAudioAdjustmentState, audioAdjustmentState, audioAdjustmentState)
SETTER_SYNCHRONIZED(IoTMediaPlayerAttr *,setMediaPlayerAttr,mediaPlayerAttr,mediaPlayerAttr)
SETTER_SYNCHRONIZED(IoTVolumeControlAttr *,setVolumeControlAttr,volumeControlAttr,volumeControlAttr)
SETTER_SYNCHRONIZED(IoTVolumeControlAttr *,setGroupVolumeControlAttr,groupVolumeControlAttr,groupVolumeControlAttr)
SETTER_SYNCHRONIZED(IoTInputSelectorAttr *,setInputSelectorAttr,inputSelectorAttr,inputSelectorAttr)
SETTER_SYNCHRONIZED(IoTOutputSelectorAttr *,setOutputSelectorAttr,outputSelectorAttr,outputSelectorAttr)
SETTER_SYNCHRONIZED(IoTGroupAttr *,setGroupAttr,groupAttr,groupAttr)
SETTER_SYNCHRONIZED(IoTPlaylistState *,setPlaylistState,playlistState,playlistState)

@end
