import Packet from "../packet";
import Stream from "../stream";

export enum SignalType {
    CALL = 0,
    KEY_EXCHANGE = 1,
    ACTIVE_CALL = 2,
    END_CALL = 3,
    /**
     * Переведен в стадию активного, значит комната на SFU уже создана и можно начинать обмен сигналами WebRTC
     */
    ACTIVE = 4,
    END_CALL_BECAUSE_PEER_DISCONNECTED = 5,
    END_CALL_BECAUSE_BUSY = 6,
    ACCEPT = 7,
    RINGING_TIMEOUT = 8
}

/**
 * Пакет сигналинга, для сигналов WebRTC используется отдельный пакет 27 PacketWebRTCExchange
 */
export class PacketSignalPeer extends Packet {

    private src: string = "";
    /**
     * Назначение
     */
    private dst: string = "";
    /**
     * Используется если SignalType == KEY_EXCHANGE, для идентификации сессии обмена ключами
     */
    private sharedPublic: string = "";

    private signalType: SignalType = SignalType.CALL;

    private callId: string = "";
    private joinToken: string = "";


    public getPacketId(): number {
        return 26;
    }

    public _receive(stream: Stream): void {
        this.signalType = stream.readInt8();
        if(this.signalType == SignalType.END_CALL_BECAUSE_BUSY 
            || this.signalType == SignalType.RINGING_TIMEOUT 
            || this.signalType == SignalType.END_CALL_BECAUSE_PEER_DISCONNECTED){
            return;
        }
        this.src = stream.readString();
        this.dst = stream.readString();
        if(this.signalType == SignalType.KEY_EXCHANGE){
            this.sharedPublic = stream.readString();
        }
        if(this.signalType == SignalType.CALL || this.signalType == SignalType.ACCEPT || this.signalType == SignalType.END_CALL){
            this.callId = stream.readString();
            this.joinToken = stream.readString();
        }
    }

    public _send(): Promise<Stream> | Stream {
        const stream = new Stream();
        stream.writeInt16(this.getPacketId());
        stream.writeInt8(this.signalType);
        if(this.signalType == SignalType.END_CALL_BECAUSE_BUSY 
            || this.signalType == SignalType.RINGING_TIMEOUT 
            || this.signalType == SignalType.END_CALL_BECAUSE_PEER_DISCONNECTED){
            return stream;
        }
        stream.writeString(this.src);
        stream.writeString(this.dst);
        if(this.signalType == SignalType.KEY_EXCHANGE){
            stream.writeString(this.sharedPublic);
        }
        if(this.signalType == SignalType.CALL || this.signalType == SignalType.ACCEPT || this.signalType == SignalType.END_CALL){
            stream.writeString(this.callId);
            stream.writeString(this.joinToken);
        }
        return stream;
    }

    public setDst(dst: string) {
        this.dst = dst;
    }

    public setSharedPublic(sharedPublic: string) {
        this.sharedPublic = sharedPublic;
    }

    public setSignalType(signalType: SignalType) {
        this.signalType = signalType;
    }

    public getDst(): string {
        return this.dst;
    }

    public getSharedPublic(): string {
        return this.sharedPublic;
    }

    public getSignalType(): SignalType {
        return this.signalType;
    }

    public getSrc(): string {
        return this.src;
    }

    public setSrc(src: string) {
        this.src = src;
    }

    public getCallId(): string {
        return this.callId;
    }

    public setCallId(callId: string) {
        this.callId = callId;
    }

    public getJoinToken(): string {
        return this.joinToken;
    }

    public setJoinToken(joinToken: string) {
        this.joinToken = joinToken;
    }
    
}