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

export enum HandshakeState {
    COMPLETED,
    NEED_DEVICE_VERIFICATION
}

export interface Device {
    deviceId: string;
    deviceName: string;
    deviceOs: string;
}

/**
 * Hadshake packet
 * ID: 0x00
 * 
 * The handshake packet is the first packet sent by the client to the server.
 * It contains the hash of the client's public key and the public key itself.
 */
export default class PacketHandshake extends Packet {
    private privateKey: string = ""; 
    private publicKey: string = "";
    private protocolVersion: number = 1;
    /**
     * Interval seconds
     */
    private heartbeatInterval : number = 15;
    private device: Device = {
        deviceId: "",
        deviceName: "",
        deviceOs: ""
    };
    private handshakeState: 
        HandshakeState = HandshakeState.NEED_DEVICE_VERIFICATION;

    public getPacketId(): number {
        return 0x00;
    }

    public _receive(stream: Stream): void {
        this.privateKey = stream.readString();
        this.publicKey = stream.readString();
        this.protocolVersion = stream.readInt8();
        this.heartbeatInterval = stream.readInt8();
        this.device = {
            deviceId: stream.readString(),
            deviceName: stream.readString(),
            deviceOs: stream.readString()
        }
        this.handshakeState = stream.readInt8();
    }

    public _send(): Stream {
        const stream = new Stream();
        stream.writeInt16(this.getPacketId());
        stream.writeString(this.privateKey);
        stream.writeString(this.publicKey);
        stream.writeInt8(this.protocolVersion);
        stream.writeInt8(this.heartbeatInterval);
        stream.writeString(this.device.deviceId);
        stream.writeString(this.device.deviceName);
        stream.writeString(this.device.deviceOs);
        stream.writeInt8(this.handshakeState);
        return stream;
    }

    public getPrivateKey(): string {
        return this.privateKey;
    }

    public getPublicKey(): string {
        return this.publicKey;
    }

    public setPrivateKey(privateKey: string): void {
        this.privateKey = privateKey;
    }

    public setPublicKey(publicKey: string): void {
        this.publicKey = publicKey;
    }

    public getProtocolVersion(): number {
        return this.protocolVersion;
    }

    public setProtocolVersion(protocolVersion: number): void {
        this.protocolVersion = protocolVersion;
    }

    public getHeartbeatInterval(): number {
        return this.heartbeatInterval;
    }

    public setHeartbeatInterval(heartbeatInterval: number): void {
        this.heartbeatInterval = heartbeatInterval;
    }

    public getDevice(): Device {
        return this.device;
    }

    public setDevice(device: Device): void {
        this.device = device;
    }

    public getHandshakeState(): HandshakeState {
        return this.handshakeState;
    }

    public setHandshakeState(handshakeState: HandshakeState): void {
        this.handshakeState = handshakeState;
    }
    
}