package baidu

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

type AsrSdk struct {
	appID     string
	apiKey    string
	secretKey string
	token     *Token
}

func NewAsrSdk(AppID, APIKey, SecretKey string) *AsrSdk {
	return &AsrSdk{
		appID:     AppID,
		apiKey:    APIKey,
		secretKey: SecretKey,
	}
}

func (s *AsrSdk) GetToken() (err error) {
	url := "https://aip.baidubce.com/oauth/2.0/token?client_id=%v&client_secret=%v&grant_type=client_credentials"
	url = fmt.Sprintf(url, s.apiKey, s.secretKey)
	payload := strings.NewReader(``)
	client := &http.Client{}
	req, err := http.NewRequest("POST", url, payload)

	if err != nil {
		fmt.Println(err)
		return
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")

	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	var token Token
	err = json.Unmarshal(body, &token)
	if err != nil {
		fmt.Println(err)
		return
	}
	s.token = &token
	return
}

func (s *AsrSdk) RefreshToken() {
	if s.token == nil || s.token.ExpiresIn < 60*60*24 {
		err := s.GetToken()
		if err != nil {
			fmt.Println(err)
			return
		}
	}
}

// Asr
//
//	@Description: ASR语音识别文字
//	@receiver s
//	@param resource
//	@param format pcm/wav/amr/m4a
//	@param rate 16000、8000
//	@return d
//	@return err
func (s *AsrSdk) Asr(src []byte, format string, rate int) (d *AsrResp, err error) {
	s.RefreshToken()
	url := "http://vop.baidu.com/server_api"
	var req AsrReq
	req.Format = format
	req.Rate = rate
	req.Channel = 1
	req.Cuid = "small_sheep_asr"
	req.Token = s.token.AccessToken
	req.Speech = base64.StdEncoding.EncodeToString(src)
	req.Len = len(src)
	bts, err := json.Marshal(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	res, err := http.Post(url, "application/json", bytes.NewBuffer(bts))
	if err != nil {
		fmt.Println(err)
		return
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	var resp AsrResp
	err = json.Unmarshal(body, &resp)
	if err != nil {
		fmt.Println(err)
		return
	}
	return &resp, nil
}
