package com.viaccessorca.voplayerdemo.demo;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

import com.viaccessorca.vodownloader.NanoHTTPD;
import com.viaccessorca.voplayer.VOPlayer;
import com.viaccessorca.voplayerdemo.Constants;
import com.viaccessorca.voplayerdemo.downloader.DownloadManager;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.HashMap;

public class FastStartupDemo implements VoDemo {

    private final static int LOCAL_SERVER_BANDWIDTH_DEFAULT_SPEED = 3600000;

    private NanoHTTPD nanoHTTPDServerSlowRef = null;
    private NanoHTTPD nanoHTTPDServerFastRef = null;
    private String mMediaUri = null;
    private WeakReference<VOPlayer> mMediaPlayer;
    private WeakReference<SeekBar> mSeekBar;
    private WeakReference<TextView> mBitrateTextView;
    private Context mAppContext = null;

    public FastStartupDemo(Context appContext){
        mAppContext = appContext;
        startLocalServer(mAppContext);
    }

    public void prepare(VOPlayer player, Uri mediaUri, View view, View view2){
        if(null != player){
            mMediaUri = mediaUri.toString();
            mSeekBar = new WeakReference<SeekBar>((SeekBar)view);
            mBitrateTextView = new WeakReference<TextView>((TextView)view2);
            mMediaPlayer = new WeakReference<VOPlayer>(player);
            //Instant startup demo
            updateLocalServer();

            Integer mFastStartup = 1;
            HashMap<String, Object> customization = new HashMap<>();
            customization.put("FastStartup", mFastStartup);
            player.setCustomMode(customization);
        }
    }

    public void updateFromEvent(int event) {
        if(WIFI_TOGGLE_EVENT == event) {
            updateLocalServer();
        }else if (PROGRESS_CHANGED_EVENT == event){
            if (null != mSeekBar.get() && null != mMediaPlayer.get()){
                int duration = mMediaPlayer.get().getDuration();
                if (0 < duration) {
                    int bufferLevel = mMediaPlayer.get().getCurrentBufferLevel();
                    int secondaryProgressValue = mMediaPlayer.get().getCurrentPosition() + mMediaPlayer.get().getCurrentBufferLevel();
                    mSeekBar.get().setSecondaryProgress(secondaryProgressValue);
                }
            }
        }else if (BITRATE_CHANGE_EVENT == event){
            if (null != mBitrateTextView.get() && null != mMediaPlayer.get()){
                int currentBitrate = mMediaPlayer.get().getHttpStreamingCurrentBitrate();
                if (null == nanoHTTPDServerSlowRef){
                    currentBitrate = 0;
                }else  if (0 == currentBitrate) {
                    currentBitrate = LOCAL_SERVER_BANDWIDTH_DEFAULT_SPEED;
                }
                mBitrateTextView.get().setText("Cur: " + (currentBitrate / 1000) + " kbps");
            }
        }
    }

    public void tearDown(){
        stopLocalServer();
    }

    /************************************************************/
    /********** Private methods for specific demos **************/
    /************************************************************/

    private void updateLocalServer(){
        boolean bNetworkConnected = false;
        WifiManager wifiMgr = (WifiManager) mAppContext.getSystemService(Context.WIFI_SERVICE);
        ConnectivityManager connectivityMgr = (ConnectivityManager) mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networksInfo[] = connectivityMgr.getAllNetworkInfo();
        for(NetworkInfo network : networksInfo){
            if (network.getState() == NetworkInfo.State.CONNECTED){
                bNetworkConnected = true;
            }
        }
        if (null != mMediaUri && true == bNetworkConnected && wifiMgr.isWifiEnabled()){
            if (mMediaUri.contains("127.0.0.1:"+ Constants.LOCAL_HTTP_SERVER_PORT_SLOW+"/")){
                startLocalServer(mAppContext);
            }else{
                stopLocalServer();
            }
        }else{
            stopLocalServer();
        }
    }

    /**
     * Starts NanoHTTPD local servers for instant startup demo
     * @return true if the server has been correctly started, false otherwise
     */
    private boolean startLocalServer(Context appContext) {
        DownloadManager DLMgr = DownloadManager.getInstance(appContext);
        DLMgr.stopLocalServer();
        try {
            if((null == nanoHTTPDServerFastRef) && (null == nanoHTTPDServerSlowRef)) {
                nanoHTTPDServerFastRef = new NanoHTTPD(Constants.LOCAL_HTTP_SERVER_PORT_FAST, new File(Constants.LOCAL_HTTP_SERVER_WWWROOT_FOR_IS));
                nanoHTTPDServerSlowRef = new NanoHTTPD(Constants.LOCAL_HTTP_SERVER_PORT_SLOW, new File(Constants.LOCAL_HTTP_SERVER_WWWROOT_FOR_IS));
                nanoHTTPDServerSlowRef.setBandwidth(LOCAL_SERVER_BANDWIDTH_DEFAULT_SPEED);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Stops  NanoHTTPD local servers for instant startup (safe)
     */
    private void stopLocalServer() {
        if(null != nanoHTTPDServerSlowRef) {
            try {
                nanoHTTPDServerSlowRef.stop();
                nanoHTTPDServerFastRef.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        nanoHTTPDServerSlowRef = null;
        nanoHTTPDServerFastRef = null;
    }
}
