package tech.glinfo.enbao.common.utils;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;

@Component
public class SpeechSynthesizerRestful {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${aliyunspeed.appKey}")
    private String appKey;

    @Autowired
    private AliGetTokenUtils aliGetTokenUtils;

    /**
     * HTTPS GET请求
     */
    public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice) {
        /**
         * 设置HTTPS GET请求：
         * 1.使用HTTPS协议
         * 2.语音识别服务域名：nls-gateway.cn-shanghai.aliyuncs.com
         * 3.语音识别接口请求路径：/stream/v1/tts
         * 4.设置必须请求参数：appkey、token、text、format、sample_rate
         * 5.设置可选请求参数：voice、volume、speech_rate、pitch_rate
         */
        String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
        url = url + "?appkey=" + appKey;
        url = url + "&token=" + aliGetTokenUtils.getToken();
        url = url + "&text=" + text;
        url = url + "&format=" + format;
        url = url + "&voice=" + voice;
        url = url + "&sample_rate=" + String.valueOf(sampleRate);
        // voice 发音人，可选，默认是xiaoyun。
        // url = url + "&voice=" + "xiaoyun";
        // volume 音量，范围是0~100，可选，默认50。
        // url = url + "&volume=" + String.valueOf(50);
        // speech_rate 语速，范围是-500~500，可选，默认是0。
        // url = url + "&speech_rate=" + String.valueOf(0);
        // pitch_rate 语调，范围是-500~500，可选，默认是0。
        // url = url + "&pitch_rate=" + String.valueOf(0);
        System.out.println("URL: " + url);
        /**
         * 发送HTTPS GET请求，处理服务端的响应。
         */
        Request request = new Request.Builder().url(url).get().build();
        try {
            long start = System.currentTimeMillis();
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            System.out.println("total latency :" + (System.currentTimeMillis() - start) + " ms");
            System.out.println(response.headers().toString());
            String contentType = response.header("Content-Type");
            if ("audio/mpeg".equals(contentType)) {
                File f = new File(audioSaveFile);
                FileOutputStream fout = new FileOutputStream(f);
                fout.write(response.body().bytes());
                fout.close();
                System.out.println("The GET request succeed!");
            } else {
                // ContentType 为 null 或者为 "application/json"
                String errorMessage = response.body().string();
                System.out.println("The GET request failed: " + errorMessage);
            }
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * HTTPS POST请求
     */
    public byte[] processPOSTRequest(String text) {
        /**
         * 设置HTTPS POST请求：
         * 1.使用HTTPS协议
         * 2.语音合成服务域名：nls-gateway.cn-shanghai.aliyuncs.com
         * 3.语音合成接口请求路径：/stream/v1/tts
         * 4.设置必须请求参数：appkey、token、text、format、sample_rate
         * 5.设置可选请求参数：voice、volume、speech_rate、pitch_rate
         */
        byte[] rtn = new byte[0];
        long start = System.currentTimeMillis();
        //一次只能300个字符
        do {
            String _text = null;
            if(text.length() > 300) {
                _text = text.substring(0, 300);
                text = text.substring(300);
            } else {
                _text = text;
            }
            String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
            JSONObject taskObject = new JSONObject();
            taskObject.put("appkey", appKey);
            taskObject.put("token", aliGetTokenUtils.getToken());
            taskObject.put("text", _text);
            taskObject.put("format", "mp3");
            taskObject.put("voice", "aitong");
            taskObject.put("sample_rate", "16000");
            // voice 发音人，可选，默认是xiaoyun。
            // taskObject.put("voice", "xiaoyun");
            // volume 音量，范围是0~100，可选，默认50。
            taskObject.put("volume", 50);
            // speech_rate 语速，范围是-500~500，可选，默认是0。
            taskObject.put("speech_rate", 0);
            // pitch_rate 语调，范围是-500~500，可选，默认是0。
            taskObject.put("pitch_rate", 0);
            String bodyContent = taskObject.toJSONString();
            System.out.println("POST Body Content: " + bodyContent);
            RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
            Request request = new Request.Builder()
                    .url(url)
                    .header("Content-Type", "application/json")
                    .post(reqBody)
                    .build();
            try {
                OkHttpClient client = new OkHttpClient();
                Response response = client.newCall(request).execute();
                String contentType = response.header("Content-Type");
                if ("audio/mpeg".equals(contentType)) {
//                    rtn = response.body().bytes();
                    // 合并两个数组
                    rtn = ByteUtils.byteCopy(rtn, response.body().bytes());
//                File f = new File(audioSaveFile);
//                FileOutputStream fout = new FileOutputStream(f);
//                fout.write(response.body().bytes());
//                fout.close();
//                System.out.println("The POST request succeed!");
                } else {
                    // ContentType 为 null 或者为 "application/json"
                    String errorMessage = response.body().string();
                    logger.info("The POST request failed: {}", errorMessage);
                }
                response.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } while (text.length() > 300);
        logger.info("转语音花费时间：{}", System.currentTimeMillis()-start);
        return rtn == null || rtn.length==0 ? null : rtn;
    }

//    public static void main(String[] args) {
//        if (args.length < 2) {
//            System.err.println("SpeechSynthesizerRestfulDemo need params: <token> <app-key>");
//            System.exit(-1);
//        }
//        String token = args[0];
//        String appkey = args[1];
//        SpeechSynthesizerRestful demo = new SpeechSynthesizerRestful(appkey, token);
//        String text = "今天是周一，天气挺好的。";
//        // 采用RFC 3986规范进行urlencode编码。
//        String textUrlEncode = text;
//        try {
//            textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
//                    .replace("+", "%20")
//                    .replace("*", "%2A")
//                    .replace("%7E", "~");
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//        System.out.println(textUrlEncode);
//        String audioSaveFile = "syAudio.wav";
//        String format = "wav";
//        int sampleRate = 16000;
//        demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "siyue");
//        //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate, "siyue");
//        System.out.println("### Game Over ###");
//    }
}