//
// {"access_token":"s0wf65p-KMzvYtH8qPu2qSX_EXLE2NaBgFHl7MZwedc7Kv_hdO0FG1QeUmBYJAGmQqJinPwFr67MRZwJee4rDnGVwhbuIfKs29N4ZJSXFP8fbAheuas08UuRe13UsdCtWSMcAFAGCW","expires_in":7200}
//
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

//SaveToPath : where the AuthToken json file is stored
//const SaveToPath = "/tmp/wechat_hitxy_token"

//AuthToken Access Token, for temporary access WechatAPI
type AuthToken struct {
	AccessToken string    `json:"access_token"`
	ExpireIn    int64     `json:"expires_in"`
	Time        time.Time `json:"created_at"`
}

//WechatAccessToken Global AccessToken
var WechatAccessToken AuthToken

//GetAccessToken returns a valid access_token for wechat_api
//    the token is auomatically renewed if it's about to expire
//    if error happens, return empty string and error
//    if success, return token string and nil
func GetAccessToken() (string, error) {
	t, err := readTokenFromFile(APIConfig.AuthTokenSaveTo)
	if isAuthTokenExpired(t) {
		t, err = renewAuthToken()
		if err != nil {
			log.Fatal("Cannot renew AccessToken from Wechat Server:")
			log.Fatal(err)
			return "", err // cannot get token
		}
	}
	WechatAccessToken = t
	return t.AccessToken, nil
}

func isAuthTokenExpired(t AuthToken) bool {
	seconds := fmt.Sprintf("%ds", t.ExpireIn) //7200s
	duration, _ := time.ParseDuration(seconds)
	expire := t.Time.Add(duration)
	return time.Now().After(expire)
}

//save token to perminant storage
func writeTokenToFile(body []byte, path string) {
	log.Printf("writing authtoken to %s\r\n", path)
	ioutil.WriteFile(path, body, 0600)
}

//read token from permenant storage
func readTokenFromFile(path string) (AuthToken, error) {
	var m AuthToken
	log.Printf("read authtoke from %s\r\n", path)
	body, err := ioutil.ReadFile(path)
	json.Unmarshal(body, &m)
	return m, err
}

//issue web request to get token from wechat
func renewAuthToken() (AuthToken, error) {
	//url := "http://vimeo.com/api/v2/brad/info.json"
	url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", APIConfig.Appid, APIConfig.AppSecret)
	var myClient = &http.Client{Timeout: 20 * time.Second}
	log.Println("renew access token from Internet api.weixin.qq.com")
	r, err := myClient.Get(url)
	if err != nil {
		log.Fatal("http access api.weixin.qq.com failed")
		log.Fatal(err)
		return AuthToken{}, err
	}
	defer r.Body.Close()

	var t AuthToken
	err = json.NewDecoder(r.Body).Decode(&t)

	if err != nil {
		return AuthToken{}, err
	}

	t.Time = time.Now()
	b, _ := json.Marshal(&t)
	writeTokenToFile(b, APIConfig.AuthTokenSaveTo)
	return t, nil
}

// //debugged http response
// func dummy() {
// 	var body []byte
// 	var response *http.Response
// 	var request *http.Request
// 	url := "http://vimeo.com/api/v2/brad/info.json"

// 	request, err := http.NewRequest("GET", url, nil)
// 	if err == nil {
// 		request.Header.Add("Content-Type", "application/json")
// 		//debug(httputil.DumpRequestOut(request, true))
// 		response, err = (&http.Client{}).Do(request)
// 	}

// 	if err == nil {
// 		defer response.Body.Close()
// 		//debug(httputil.DumpResponse(response, true))
// 		body, err = ioutil.ReadAll(response.Body)
// 		//json.NewDecoder(response.Body).Decode(m)
// 	}

// 	if err == nil {
// 		writeTokenToFile(body, "/tmp/wechat_hitxy_token")
// 		//m.Time = time.Now()
// 	} else {
// 		log.Fatalf("ERROR: %s", err)
// 	}
// }
