package com.wasu.cs.module;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;

import com.wasu.authsdk.AuthSDK;
import com.wasu.authsdk.IAuthInterface;
import com.wasu.cs.utils.Base64;
import com.wasu.module.http.HttpRequestModule;
import com.wasu.module.http.RequestParams;
import com.wasu.module.log.WLog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import basic.app.TvAppLike;
import cn.com.wasu.main.BuildConfig;
import cn.com.wasu.main.ChannelFlavor;
import cn.com.wasu.main.Common;

/**
 * 顺序异步执行:
 * getPlayUrl   ---> get UTC time  --->    getVideUrl    --->    getPlayUrl
 * 外部调用      ---> 获取UTC时间   ---> 获取播放流请求URL --->  获取并返回播放流(HLS协议)
 * <p>
 * Created by danxingxi on 2016/5/12.
 * 咪咕认证鉴权和播放流获取模块
 */
public class AuthMiguModule {
    private static final String TAG = "AuthMiguModule";

    private static final int CALLBACK = -1;
    /**
     * 渠道id
     **/
    private static final String channelid = "0119_61080001-99000-101400000000001";
    /**
     * 合作伙伴id
     **/
    public static final String partnerid = "1002021";
    /**
     * 产品id
     **/
    public static final String productid = "2028593060";
    /**
     * 节目id 由华数WCMS下发，这里为测试用的id
     **/
    public String contentid = "618765126";
    /**
     * 第一步验证权限url
     **/
    public static final String authUrl = "http://aep.cmvideo.cn:1100/streamingapi/getPushUserInfoUrl/v1";
    /**
     * 第二步获取视频流url
     **/
    public static final String videoUrl = "http://aep.cmvideo.cn:1100/pushUserInfo/v1";

    private static AuthMiguModule mInstance;
    /**
     * 网络请求线程
     **/
    private HandlerThread requestThread;
    /**
     * 网络请求线程的Handler
     */
    private Handler requestThreadHandler;

    private Context mContext;

    private AuthMiguCallBack callBack;
    /*是否停止线程*/
    private boolean stopThread = false;

    /* private的构造函数用于避免外界直接使用new来实例化对象 */
    private AuthMiguModule() {
    }


    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CALLBACK) {
                if (callBack != null) {
                    if (msg.arg1 == -1) {
                        callBack.result("-1", "获取播放流失败", "");
                    } else if (msg.arg1 == 0) {
                        callBack.result("0", "SUCCESS", playUrl);
                    }
                }
            }
        }
    };

    /**
     * 获取单例
     *
     * @return
     */
    public static AuthMiguModule getInstance() {
        if (null == mInstance) {
            synchronized (AuthMiguModule.class) {
                if (null == mInstance) {
                    mInstance = new AuthMiguModule();
                }
            }
        }
        return mInstance;
    }

    public void init(Context context) {
        mContext = context;
    }

    /**
     * 获取咪咕视频播放流 对外接口
     *
     * @param mContentid       资产ID
     * @param authMiguCallBack 获取回调
     */
    public void getPlayUrl(String mContentid, AuthMiguCallBack authMiguCallBack) {
        if (mContentid == null || TextUtils.isEmpty(mContentid) || authMiguCallBack == null) {
            throw new IllegalArgumentException("参数不能为空");

        }
        stopThread = false;
        this.contentid = mContentid;
        this.callBack = authMiguCallBack;
        if (requestThread == null) {
            requestThread = new HandlerThread("requestThread");
            requestThread.start();
        }
        if (requestThreadHandler == null) {
            requestThreadHandler = new Handler(requestThread.getLooper());
        }
        requestThreadHandler.post(new GetUTCTask());
    }

    /**
     * 根据contentid请求获取播放流的URL
     *
     * @param mContentid 资产id
     * @param mCreated   实时时间
     */
    private void getVideoUrl(String mContentid, String mCreated) {

        /**请求header**/
        final Map<String, String> header = new HashMap<String, String>();

        header.put("User-Agent", "Dalvik/v3.1.31 (Linux; U; Android 1.2.0-R-20140505.1720; WASU_A200f Build/JDQ39)");
        header.put("Referer", "http://cms.wasu.tv");
        /**app请求时产生的一个随机数**/
        String Nonce = "6c2e8a85717641a79c71c13109d6d2e6";

        /**随机数生成时间**/
        String Created = mCreated;
        String strTemp = Nonce + Created + Common.miguSecretKey;
        String passwordDigest = string2SHA2Base64(strTemp);
        /**header部分Authorization参数**/
        String Authorization = "WSSE realm=\"SDP\", profile=\"UsernameToken\", type=\"AppKey\"";
        /**header部分X-WSSE参数**/
        StringBuffer sbXWSSE = new StringBuffer();

        sbXWSSE.append(" UsernameToken ");
        sbXWSSE.append(" Username = " + "\"" + Common.miguAppKey + "\",");
        sbXWSSE.append(" PasswordDigest=" + "\"" + passwordDigest + "\",");
        sbXWSSE.append(" Nonce=" + "\"" + Nonce + "\",");
        sbXWSSE.append(" Created=" + "\"" + Created + "\"");

        WLog.d(TAG, "X-WSSE-->" + sbXWSSE.toString());

        header.put("Host", "aep.sdp.com");
        header.put("Authorization", Authorization);
        header.put("X-WSSE", sbXWSSE.toString());

        WLog.d(TAG, "header-->" + header.toString());

        /**组装请求body**/
        String requestBody = "{\"partnerid\":\"" + partnerid + "\",\"channelid\":\"" + channelid + "\",\"contentid\":\"" +
                contentid + "\",\"productid\":\"" + productid + "\",\"ratelevel\":\"3\",\"nettype\":\"4\"}";
        RequestParams params = new RequestParams(RequestParams.Method.POST, authUrl, header, requestBody.getBytes(), new RequestParams.RequestListener() {
            @Override
            public boolean onResponse(int i, String s, int i1, Object o) {
                if (s != null) {
                    try {
                        JSONObject jsonObject = new JSONObject(s);
                        String resultcode = jsonObject.optString("resultcode");
                        String desc = jsonObject.optString("desc", "error");
                        String url = jsonObject.optString("playurl", "");
                        if (TextUtils.isEmpty(url)) {
                            if (callBack != null) {
                                WLog.e(TAG, "咪咕视频流获取失败，请检查参数后重试！");
                                callBack.result(resultcode, desc, "");
                            }
                        } else {
                            requestThreadHandler.post(new GetPlayerUrlTask(url, header));
                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    //生成异常并抛出
                    throw new IllegalArgumentException("请检查请求参数是否正确!");
                }

                return false;
            }
        });
        HttpRequestModule.getInstance().addTask(params);
    }

    /**
     * 获取视频播放流
     */
    String playUrl;

    class GetPlayerUrlTask implements Runnable {
        String url;
        Map<String, String> header;

        public GetPlayerUrlTask(String mUrl, Map<String, String> mHeader) {
            WLog.d(TAG, "IP--->" + TvAppLike.getIpAddress());
            String tvid = AuthSDK.getInstance().getValue(IAuthInterface.KEY_TVID);
            WLog.d(TAG, "TVID--->" + tvid);
            this.url = mUrl + "&Id_type=2" + "&userid=" + tvid + "&ipaddress=" + TvAppLike.getIpAddress();
            this.header = mHeader;
        }

        @Override
        public void run() {
            if (!stopThread) {
                try {
                    URL url2 = new URL(url);
                    HttpURLConnection conn = (HttpURLConnection) url2.openConnection();//生成连接对象

                    conn.setRequestProperty("Host", header.get("Host"));
                    conn.setRequestProperty("Authorization", header.get("Authorization"));
                    conn.setRequestProperty("X-WSSE", header.get("X-WSSE"));
                    conn.setRequestMethod("GET");
                    /**禁止重定向**/
                    conn.setInstanceFollowRedirects(false);
                    conn.connect(); //发出连接

                    playUrl = conn.getHeaderField("Location");
                    Message msg = new Message();
                    msg.what = CALLBACK;
                    if (playUrl != null && !TextUtils.isEmpty(playUrl)) {
                        WLog.d(TAG, "Location-->" + playUrl);
                        /*if (callBack != null) {
                            callBack.result("0", "SUCCESS", playUrl);
                        }*/
                        msg.arg1 = 0;
                    } else {
                        /*callBack.result("-1", "获取播放流失败", "");*/
                        msg.arg1 = -1;
                    }
                    handler.sendMessage(msg);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 从网络获取UTC标准时间
     */
    class GetUTCTask implements Runnable {

        public GetUTCTask() {
        }

        @Override
        public void run() {
            if (!stopThread) {
                URL url = null;//取得资源对象
                String Created = null;
                try {
                    url = new URL((BuildConfig.FLAVOR.equalsIgnoreCase(ChannelFlavor.LETV_MARKET) ? "https://letv-ds.wasu.tv" : "http://tang-ds.cs.wasu.tv") + "/now");
                    HttpURLConnection uc = (HttpURLConnection) url.openConnection();//生成连接对象
                    uc.connect(); //发出连接
                    InputStream inStrm = uc.getInputStream();
                    String result = getEncodedData(inStrm);
                    WLog.d(TAG, "result-->" + result);
                    if (result == null || result.equals("")) {
                        if (callBack != null) {
                            callBack.result("-1", "获取UTC时间失败", "");
                        }
                        return;
                    }
                    inStrm.close();
                    String strTime = result.split("\\.")[0] + result.split("\\.")[1];
                    WLog.d(TAG, "strTime-->" + strTime);
                    long ld = Long.parseLong(strTime.trim());
//                    long ld = uc.getDate(); //取得网站日期时间
                    Date date = new Date(ld); //转换为标准时间对象
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                    format.setTimeZone(TimeZone.getTimeZone("UTC"));
                    Created = format.format(date);
                    if (Created != null) {
                        WLog.d(TAG, "UTC time:" + Created);
                        getVideoUrl(contentid, Created);
                    } else {
                        if (callBack != null) {
                            callBack.result("-1", "获取UTC时间失败", "");
                        }
                    }

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 此方法用于从输入流中获取数据
     *
     * @param is 接收来自客户端socket对应的输入流
     * @return 返回endodedData
     * @throws IOException 抛出的异常，统一在run函数处理
     */
    private String getEncodedData(InputStream is) throws IOException {
        byte[] maxBuffer = new byte[1024 * 64];
        int length = 0;
        int lengthTemp = 0;
        while (-1 != (lengthTemp = is.read(maxBuffer))) {
            length += lengthTemp;
            if (length >= 1024 * 64) {
                WLog.d(TAG, "读入的数据超过1024 * 64");
                break;
            }
        }

        byte[] endodedData = new byte[length];
        System.arraycopy(maxBuffer, 0, endodedData, 0, length);

        return new String(endodedData);
    }

    /**
     * 请求咪咕视频播放流回调接口
     */
    public interface AuthMiguCallBack {
        /**
         * @param resultcode 结果码，0表示成功，其它表示失败。
         * @param desc       结果描述信息。
         * @param playUrl    播放流，请求成功后返回播放流，请求失败返回""空字符串
         */
        public void result(String resultcode, String desc, String playUrl);
    }

    /**
     * 移除回调监听
     */
    public void removeCallBackLisenter(){
        if(callBack!=null){
            callBack = null;
        }
    }

    /**
     * 把一个字符串先进行HA256加密，然后转换为Base64的格式
     *
     * @return
     */
    private String string2SHA2Base64(String str) {
        if (str != null) {
            byte[] passwd = str.getBytes();
            MessageDigest alga = null;
            try {
                alga = MessageDigest.getInstance("SHA-256");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            byte[] strSha = alga.digest(passwd);
            return Base64.encodeToString(strSha, false);
        } else {
            return null;
        }
    }

    /**
     * app退出后消废线程
     */
    public void destory() {
        stopThread = true;
        if (requestThread != null) {
            requestThread.quit();
            requestThread.interrupt();
        }
        WLog.d(TAG, "destory authmigumodule");
    }

}
