const IceCastPlayer = require('./clsPlayer').clsPlayer;


const iceCastPlayer = class iceCastPlayer {
    constructor({ config, util, logger, masterMixer }) {
        this.config = config;
        this.util = util;
        this.mixer = masterMixer;
        this.logger = logger;
        this.serverAddress = this.config.iceCast.ServerAddress + ':' +
            this.config.iceCast.ServerPort + '/' + this.config.iceCast.ServerMountPoint;
        this.serverPassword = this.config.iceCast.ServerPass;
        this.serverPublic = this.config.iceCast.ServerPublic;
        this.mode = this.config.iceCast.Mode;
        this.bitrate = this.config.iceCast.Bitrate;
        this.quality = this.config.iceCast.Quality;
        this.sampleRate = this.config.iceCast.SampleRate;
        this.hasLocalOutput = this.config.iceCast.hasLocalOutput;
        this.genre = this.config.iceCast.Genre;
        this.lameOptions = `lame -r -V ${this.mode} -b${this.bitrate} - `;
        this.url = this.serverAddress;
        this.desc = this.config.iceCast.ServerMountPoint + ' live stream';
        this.serverHeader = '';
        this.serverName = this.config.iceCast.ServerMountPoint;
        this.status = 0;
        this.encoder = 0;

        let icePlayer = new IceCastPlayer();
        this._icePlayer = icePlayer;

        this.eventTypes = {
            iceCastPlaying: 'iceCastPlaying',
            iceCastStopped: 'iceCastStopped',
            Error: 'Error',
            connectionStatus: 'connectionStatus'
        };

        icePlayer.initSoundCard(this.config.Settings.soundCard, icePlayer.bassAttributes.BASS_DEVICE_STEREO);
        this.logger.IceCastPlayer('Icecast initialized');
    }

    start() {
        if (this.encoder == 0) {
            this.encoder = this._icePlayer.iceCastEncoder(this.mixer, this.lameOptions);
            if (this.encoder == 0) {
                let err = this._icePlayer.getError();
                this.logger.iceCast('Cant encode mixer, err: ' + err);
                setTimeout(() => {
                    this.start();
                    return;
                }, 2000);
                return;
            }
            let castInit = this._icePlayer.encodeCastInit(this.encoder, this.serverAddress, this.serverPassword, this.serverName, this.url, this.genre, this.desc, this.serverHeader, this.bitrate, this.serverPublic);
            if (castInit != 1) {
                let err = this._icePlayer.getError();
                this.logger.IceCastPlayer(`castInit: ${castInit} , err: ${this._icePlayer.getError()}`);
                setTimeout(() => {
                    this.stop();
                    return;
                }, 2000);
                return;
            }
            let interval = setInterval(() => {
                let health = this.checkIceCastHealth();
                this.logger.iceCast(`icecast health: ${health}`);
                if (!health) {
                    setTimeout(() => {
                        this.stop();
                    }, 2000);
                    return;
                }
            }, 10000);
        }
    }

    stop() {
        if (this.encoder != 0) {
            this._icePlayer.encodeStop(this.encoder);
            this.logger.iceCast('Stopped encoder, starting back in a second');
            this.encoder = 0;
        }
        setTimeout(() => {
            this.start();
        }, 2000);
        return;
    }

    // notify() {
    //     let notify = this._icePlayer.setNotify(this.encoder, (proc) => {
    //         let health = this.checkIceCastHealth();
    //         if(!health) {
    //             setTimeout(() => {
    //                 this.stop();
    //                 if(interval) {
    //                     clearInterval(interval);
    //                 }
    //             }, 2000);
    //             return;
    //         }
    //         this.logger.iceCast(`notify event, proc: ${proc}, enc: ${this.encoder}`);
    //     });
    //     let interval = setInterval(() => {
    //         let health = this.checkIceCastHealth();
    //         this.logger.iceCast(`icecast health: ${health}`);
    //
    //         if(!health) {
    //             setTimeout(() => {
    //                 this.stop();
    //             }, 2000);
    //             return;
    //         }
    //     }, 10000);
    // }

    checkIceCastHealth() {
        if (this.encoder != 0) {
            let status = this._icePlayer.isEncoderActive(this.encoder);
            if (status != 1) {
                this.logger.iceCast('IceCast is not running');
                return false;
            }
            return true;
        }
    }

    setTitle(encoder, title) {
        try {
            return this._icePlayer.setStreamTitle(encoder, title);
        } catch (e) {
            this.logger.iceCast('Err setting title: ' + e.message);
        }
    }

    /*
    local icecast server for test purpose
     */
    // iceCastLocal(mixer) {
    //     this.mixer = mixer;
    //     this.encoder = this._icePlayer.iceCastEncoder(mixer, this.lameOptions);
    //     if(this.encoder == 0) {
    //         this.logger.iceCast('Cant encode mixer');
    //     }
    //     let castInit =this._icePlayer.encodeCastInit(this.encoder, 'http://localhost:8000/', 'hackme', this.serverName, this.url, this.genre, this.desc, this.serverHeader, this.sampleRate, this.serverPublic);
    //     let err = this._icePlayer.getError();
    //     if(err != 0) {
    //         this.logger.IceCastPlayer(`Err on stream: ${err}`);
    //     }
    //     if(err == 40 || castInit == 40) {
    //         this.logger.iceCast('Server is not running, timeout error');
    //     }
    //     if(err == 2100) {
    //         this.logger.iceCast('Icecast err: Access denied. Invalid password');
    //     }
    //     let notify = this._icePlayer.setNotify(this.encoder, (callback) => {
    //         if(callback) {
    //             setTimeout(() => {
    //                 this.iceCastLocal(this.mixer);
    //             }, 2000);
    //             return;
    //         }
    //     });
    // }
};

const util = require('util');
const EventEmitter = require('events').EventEmitter;
util.inherits(iceCastPlayer, EventEmitter);
module.exports = iceCastPlayer;
