package main

//swwebservice

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"errors"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"time"
)

func dailTimeout(network, addr string) (net.Conn, error) {
	//	default_timeout := time.Duration(theSession.DefaultTimeout) * time.Second
	default_timeout := time.Duration(3) * time.Second
	return net.DialTimeout(network, addr, default_timeout)
}

type WebSession struct {
	AppId          string
	TermId         string
	Appsecret      string
	BaseUrl        string
	DefaultTimeout int
	session_key    string
}

type MessageReader struct {
	FuncNo      int
	ColumnNames []string
	ColumnDescs []string
	RowData     [][]interface{}
}

type MessageWriter struct {
	FuncNo      int
	Attributes  map[string]string
	ColumnNames []string
	ColumnDescs []string
	RowData     [][]interface{}
}

func NewMessageWriter(funcno int) *MessageWriter {
	return &MessageWriter{
		FuncNo:      funcno,
		Attributes:  make(map[string]string),
		ColumnNames: make([]string, 0),
		ColumnDescs: make([]string, 0)}
}
func (m *MessageWriter) SetAttr(name, value string) {
	m.Attributes[name] = value
}
func (m *MessageWriter) AddCol(name, desc string) {
	m.ColumnNames = append(m.ColumnNames, name)
	m.ColumnDescs = append(m.ColumnDescs, desc)
}
func (m *MessageWriter) AddRow(data []string) {
	//	m.RowData[] = append(m.RowData)
}

func (w *WebSession) DoGet(uri string, params map[string]string) (*http.Response, error) {
	transport := http.Transport{Dial: dailTimeout}

	client := http.Client{Transport: &transport}

	full_url := w.BaseUrl + uri

	vl := url.Values{}
	//	vl.Add("app_id", w.AppId)
	//	ts := w.GetTimestamp()
	//	vl.Add("timestamp", ts)

	if params != nil {
		for k, v := range params {
			vl.Add(k, v)
		}
	}
	//	vl.Add("sign", w.Sign(ts, vl.Encode()))
	full_url = full_url + "?" + vl.Encode()
	fmt.Printf("url: %v\n", full_url)
	return client.Get(full_url)
}

func (w *WebSession) GetTimestamp() string {
	t := time.Now()
	return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
		t.Hour(), t.Minute(), t.Second())
}

func (w *WebSession) Sign(message string) string {
	//	pridata := accesstoken + timestamp
	mac := hmac.New(sha1.New, []byte(w.session_key))
	mac.Write([]byte(message))
	res := mac.Sum(nil)
	//	res := sha1.Sum([]byte(pridata))
	return string(res[0:])
}

func (w *WebSession) DoPost(uri string, param map[string]string, json_data []byte) (*http.Response, error) {
	transport := http.Transport{Dial: dailTimeout}
	client := &http.Client{Transport: &transport}
	vl := url.Values{}
	vl.Add("app_id", w.AppId)
	ts := w.GetTimestamp()
	vl.Add("timestamp", ts)
	vl.Add("sign", w.Sign(ts+vl.Encode()))
	if param != nil {
		for k, v := range param {
			vl.Add(k, v)
		}
	}
	if json_data != nil {
		vl.Add("request_data", string(json_data))
	}

	full_url := w.BaseUrl + uri
	log.Debugf("Url=%v", full_url)
	r, err := client.Post(full_url, "application/x-www-form-urlencoded", bytes.NewReader([]byte(vl.Encode())))
	if err != nil || r.StatusCode != 200 {
		log.Errorf("Status=%v, err=%v", r, err)
	}
	return r, err
}

func (w *WebSession) Auth() error {
	token, err := w.getAuthToken()
	if err != nil {
		return err
	}
	err = w.getAppAccessKey(token)
	if err != nil {
		return err
	}
	return nil
}

func NewSession(appid, appsecret, termid, baseurl string, timeout int) *WebSession {
	return &WebSession{
		AppId:          appid,
		Appsecret:      appsecret,
		TermId:         termid,
		BaseUrl:        baseurl,
		DefaultTimeout: timeout,
	}
}

func (w *WebSession) getAuthToken() (string, error) {
	type FormJson struct {
		AppId       string `json:"app_id"`
		TermId      string `json:"term_id"`
		AccessToken string `json:"access_token"`
	}

	uri := fmt.Sprintf("/yktapi/services/authservice/getauth/%v/getaccesstoken", w.AppId)

	params := make(map[string]string)
	params["term_id"] = w.TermId
	r, err := w.DoGet(uri, params)

	if err != nil || r.StatusCode != 200 {
		fmt.Println("here")
		//		log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
		return "", errors.New("请求失败")
	}

	body, err := ioutil.ReadAll(r.Body)
	r.Body.Close()

	s := &FormJson{}
	err = json.Unmarshal(body, &s)
	if err != nil {
		log.Errorf("json unmarshal err %v", err)
		return "", errors.New("解析失败")
	}
	return s.AccessToken, nil
}
func (w *WebSession) getAppAccessKey(token string) error {
	type FormJson struct {
		AppId      string `json:"app_id"`
		TermId     string `json:"term_id"`
		SessionKey string `json:"session_key"`
		CardKey    string `json:"card_key"`
	}

	uri := fmt.Sprintf("/yktapi/services/authservice/getauth/%v", w.AppId)

	params := make(map[string]string)
	params["term_id"] = w.TermId
	params["access_token"] = token
	params["timestamp"] = w.GetTimestamp()
	params["v"] = "1"
	params["sign"] = w.Sign(token + params["timestamp"])
	params["sign_method"] = "HMAC"

	r, err := w.DoGet(uri, params)
	if err != nil || r.StatusCode != 200 {
		log.Errorf(" err = %v\n", err)
		return err
	}

	body, err := ioutil.ReadAll(r.Body)
	r.Body.Close()
	//	contents := make([]byte, r.ContentLength)
	//	r.Body.Read(contents)

	s := &FormJson{}
	err = json.Unmarshal(body, &s)
	fmt.Printf("[%v]\n", string(body))
	if err != nil {
		log.Errorf("json unmarshal err %v", err)
	}
	w.session_key = s.SessionKey
	return nil
}
func (w *WebSession) PushTransdtl(msg MessageWriter) {
	type FormJson struct {
	}
	//	uri := fmt.Sprintf("/yktapi/services/ecardservice")

	//	params := make(map[string]string)
	//	params["term_id"] = w.TermId
	//	params["access_token"] = w.AccessToken
	//	params["timestamp"] = w.GetTimestamp()
	//	signMsg := w.AppId + w.TermId + w.session_key + params["timestamp"]
	//	params["sign"] = w.Sign(signMsg)
	//	params["sign_method"] = "HMAC-SHA1"
	//	temp := json.Marshal(msg)
	//	params["funcdata"] = string(temp[0:])

	//	r, err := w.DoPost(uri, params, nil)
	//	if err != nil || r.StatusCode != 200 {
	//		log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
	//		return
	//	}
	//	if r.ContentLength == -1 {
	//		log.Error("no response")
	//		return
	//	}
	//	contents := make([]byte, r.ContentLength)
	//	r.Body.Read(contents)

	//	var s FormJson
	//	err = json.Unmarshal(contents, &s)
	//	if err != nil {
	//		log.Errorf("json unmarshal err %v", err)
	//		return
	//	}
	//		temp = s.
}

func main() {
	websession := NewSession("10001", "", "100", "http://172.28.200.122:8080", 3)
	fmt.Println(websession.AppId)
	if err := websession.Auth(); err != nil {
		fmt.Printf("Error : %v\n", err)
	}
	//	websession.GetAppAccessKey()

}
