package main

//swwebservice

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"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
	AccessToken    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()
	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 {

	//	now := time.Now()
	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() {
	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/%06d/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
	}

	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)
	}

	w.AccessToken = s.AccessToken

	return
}
func (w *WebSession) GetAppAccessKey() {
	type FormJson struct {
		AppId       string `json:"app_id"`
		TermId      string `json:"term_id"`
		session_key string `json:"session_key"`
		card_key    string `json:"card_key"`
	}

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

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

	r, err := w.DoPost(uri, params, nil)
	if err != nil || r.StatusCode != 200 {
		log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
	}
	if r.ContentLength == -1 {
		log.Error("no response")
	}
	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)
	}
	w.session_key = s.session_key
	//keep card_keyl
	return
}
func (w *WebSession) PushTransdtl(msg MessageWriter) {
	type FormJson struct {
	}
	//	uri := fmt.Sprintf("/yktapi/services/authservice/getauth/%06d", w.AppId)

	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"
	//	params["funcdata"] = msg
}

func main() {
	websession := NewSession("10001", "", "100", "172.28.200.122:8080", 3)
	fmt.Println(websession.AppId)
	websession.GetAuthToken()
	//	websession.GetAppAccessKey()

}
