// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { Features } from '@azure/communication-calling';
/**
 * @private
 */
export class ProxyCallCommon {
    constructor(context) {
        this._context = context;
    }
    unsubscribe() {
        /** No subscriptions yet. But there will be one for transfer feature soon. */
    }
    getContext() {
        return this._context;
    }
    get(target, prop) {
        switch (prop) {
            case 'mute':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.mute(...args);
                        });
                    }, 'Call.mute');
                }
            case 'unmute':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.unmute(...args);
                        });
                    }, 'Call.unmute');
                }
            case 'startVideo':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.startVideo(...args);
                        });
                    }, 'Call.startVideo');
                }
            case 'stopVideo':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.stopVideo(...args);
                        });
                    }, 'Call.stopVideo');
                }
            case 'startScreenSharing':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.startScreenSharing(...args);
                        });
                    }, 'Call.startScreenSharing');
                }
            case 'stopScreenSharing':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.stopScreenSharing(...args);
                        });
                    }, 'Call.stopScreenSharing');
                }
            case 'hold':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.hold(...args);
                        });
                    }, 'Call.hold');
                }
            case 'resume':
                {
                    return this._context.withAsyncErrorTeedToState(function (...args) {
                        return __awaiter(this, void 0, void 0, function* () {
                            return yield target.resume(...args);
                        });
                    }, 'Call.resume');
                }
            case 'feature':
                {
                    // these are mini version of Proxy object - if it grows too big, a real Proxy object should be used.
                    return this._context.withErrorTeedToState((...args) => {
                        if (args[0] === Features.Captions) {
                            const captionsFeature = target.feature(Features.Captions);
                            let proxyFeature;
                            if (captionsFeature.captions.kind === 'Captions') {
                                proxyFeature = new ProxyCaptions(this._context, target);
                                return {
                                    captions: new Proxy(captionsFeature.captions, proxyFeature),
                                    on: (...args) => {
                                        const isCaptionsKindChanged = args[0] === 'CaptionsKindChanged';
                                        if (isCaptionsKindChanged) {
                                            const listener = args[1];
                                            const newListener = () => {
                                                listener();
                                            };
                                            return captionsFeature.on('CaptionsKindChanged', newListener);
                                        }
                                    },
                                    off: (...args) => {
                                        const isCaptionsKindChanged = args[0] === 'CaptionsKindChanged';
                                        if (isCaptionsKindChanged) {
                                            return captionsFeature.off('CaptionsKindChanged', args[1]);
                                        }
                                    }
                                };
                            }
                            proxyFeature = new ProxyTeamsCaptions(this._context, target);
                            return {
                                captions: new Proxy(captionsFeature.captions, proxyFeature)
                            };
                        }
                        if (args[0] === Features.Transfer) {
                            const transferFeature = target.feature(Features.Transfer);
                            const proxyFeature = new ProxyTransferCallFeature(this._context, target);
                            return new Proxy(transferFeature, proxyFeature);
                        }
                        if (args[0] === Features.Spotlight) {
                            const spotlightFeature = target.feature(Features.Spotlight);
                            const proxyFeature = new ProxySpotlightCallFeature(this._context);
                            return new Proxy(spotlightFeature, proxyFeature);
                        }
                        if (args[0] === Features.RealTimeText && this._context.getState().userId.kind === 'microsoftTeamsUser') {
                            return;
                        }
                        return target.feature(...args);
                    }, 'Call.feature');
                }
            default:
                return Reflect.get(target, prop);
        }
    }
}
/**
 * @private
 */
class ProxyTeamsCaptions {
    constructor(context, call) {
        this._context = context;
        this._call = call;
    }
    get(target, prop) {
        switch (prop) {
            case 'startCaptions':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    this._context.setStartCaptionsInProgress(this._call.id, true);
                    try {
                        const ret = yield target.startCaptions(...args);
                        this._context.setSelectedSpokenLanguage(this._call.id, (_b = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.spokenLanguage) !== null && _b !== void 0 ? _b : 'en-us');
                        return ret;
                    }
                    catch (e) {
                        this._context.setStartCaptionsInProgress(this._call.id, false);
                        throw e;
                    }
                }), 'Call.feature');
                break;
            case 'stopCaptions':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.stopCaptions(...args);
                    this._context.setIsCaptionActive(this._call.id, false);
                    this._context.setStartCaptionsInProgress(this._call.id, false);
                    this._context.clearCaptions(this._call.id);
                    return ret;
                }), 'Call.feature');
            case 'setSpokenLanguage':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.setSpokenLanguage(...args);
                    this._context.setSelectedSpokenLanguage(this._call.id, args[0]);
                    return ret;
                }), 'Call.feature');
            case 'setCaptionLanguage':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.setCaptionLanguage(...args);
                    this._context.setSelectedCaptionLanguage(this._call.id, args[0]);
                    return ret;
                }), 'Call.feature');
            default:
                return Reflect.get(target, prop);
        }
    }
}
/**
 * @private
 */
class ProxyCaptions {
    constructor(context, call) {
        this._context = context;
        this._call = call;
    }
    get(target, prop) {
        switch (prop) {
            case 'startCaptions':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    this._context.setStartCaptionsInProgress(this._call.id, true);
                    try {
                        const ret = yield target.startCaptions(...args);
                        this._context.setSelectedSpokenLanguage(this._call.id, (_b = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.spokenLanguage) !== null && _b !== void 0 ? _b : 'en-us');
                        return ret;
                    }
                    catch (e) {
                        this._context.setStartCaptionsInProgress(this._call.id, false);
                        throw e;
                    }
                }), 'Call.feature');
                break;
            case 'stopCaptions':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.stopCaptions(...args);
                    this._context.setIsCaptionActive(this._call.id, false);
                    this._context.setStartCaptionsInProgress(this._call.id, false);
                    this._context.clearCaptions(this._call.id);
                    return ret;
                }), 'Call.feature');
            case 'setSpokenLanguage':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.setSpokenLanguage(...args);
                    this._context.setSelectedSpokenLanguage(this._call.id, args[0]);
                    return ret;
                }), 'Call.feature');
            default:
                return Reflect.get(target, prop);
        }
    }
}
/**
 * @private
 */
class ProxySpotlightCallFeature {
    constructor(context) {
        this._context = context;
    }
    get(target, prop) {
        switch (prop) {
            case 'startSpotlight':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.startSpotlight(...args);
                    return ret;
                }), 'Call.feature');
                break;
            case 'stopSpotlight':
                return this._context.withAsyncErrorTeedToState((...args) => __awaiter(this, void 0, void 0, function* () {
                    const ret = yield target.stopSpotlight(...args);
                    return ret;
                }), 'Call.feature');
            default:
                return Reflect.get(target, prop);
        }
    }
}
/**
 * @private
 */
class ProxyTransferCallFeature {
    constructor(context, call) {
        this._context = context;
        this._call = call;
    }
    get(target, prop) {
        switch (prop) {
            case 'on':
                return (...args) => {
                    const isTransferAccepted = args[0] === 'transferAccepted';
                    if (isTransferAccepted) {
                        const listener = args[1];
                        const newListener = (args) => {
                            this._context.setAcceptedTransfer(this._call.id, {
                                callId: args.targetCall.id,
                                timestamp: new Date()
                            });
                            listener(args);
                        };
                        return target.on('transferAccepted', newListener);
                    }
                };
            default:
                return Reflect.get(target, prop);
        }
    }
}
//# sourceMappingURL=CallDeclarativeCommon.js.map