package main

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"
	"testing"
)

//when we setup wechate parameters,we chat will verify us
func TestInitialSetup(t *testing.T) {

	SetupConfig()

	req := buildReqWechatAPISetup()

	rr, _ := getHTTPResponse(req, answerInitialAuth)

	// Check the response body is what we expect.
	expected := `913461463450840893`
	if rr.Body.String() != expected {
		t.Errorf("handler returned unexpected body: got %v want %v",
			rr.Body.String(), expected)
	}
}

func TestWebRootHandler(t *testing.T) {
	SetupConfig()
	req := buildReqWechatWebRoot()
	rr, _ := getHTTPResponse(req, webrootHandler)

	// Check the response body is what we expect.
	expected := `Hi there, I love dummydir!
echostr => [913461463450840893]`

	if rr.Body.String() != expected {
		t.Errorf("handler returned unexpected body: got %v want %v",
			rr.Body.String(), expected)
	}

}

//Send encrypted text Message ("test"")to server and get encrypted feedback
//we only check decrypted ToUserName should be the one we sent out.
//as decrypt itself is already a good proof of its working state.
func TestPostTxtMsg(t *testing.T) {
	SetupConfig()
	req := buildReqWechatPostTxtMsg()
	rr, _ := getHTTPResponse(req, apiV1Main)

	m := ReadEncryptedMsg(rr.Body.String())
	xml := Decode(m.Encrypt)
	h := ReadCommonHeader(xml)

	expected := "oUN420bxqFqlx0ZQHciUOesZO3PE"
	if h.ToUserName != expected {
		t.Errorf("expect ToUserName: %v \r\nbut got %v",
			expected, h.ToUserName)
	}

}

func getHTTPResponse(req *http.Request, handler http.HandlerFunc) (rr *httptest.ResponseRecorder, err error) {

	// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
	// directly and pass in our Request and ResponseRecorder.
	rr = httptest.NewRecorder()

	handler.ServeHTTP(rr, req)

	// Check the status code is what we expect.
	if status := rr.Code; status != http.StatusOK {
		err = fmt.Errorf("wrong HTTP status code: got %v want %v",
			status, http.StatusOK)
	}
	return
}

// POST /api?signature=f06bb28c1d3847815d498fc0a343b11b4d03e095&timestamp=1493212928&nonce=1461107899&openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f HTTP/1.1
// Host: wechat.hitxy.org.au
// Accept: */*
// Cache-Control: no-cache
// Connection: Keep-Alive
// Content-Length: 534
// Content-Type: text/xml
// Pragma: no-cache
// User-Agent: Mozilla/4.0
// X-Forwarded-For: 103.7.30.105
// X-Forwarded-Host: wechat.hitxy.org.au
// X-Forwarded-Server: wechat.hitxy.org.au

// <xml>
//     <ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
//     <Encrypt><![CDATA[HKILXQjAOV4Zi5Zb8gQ8zt6EPA6cBCRYSq90PZuyMqZSGhtjMESSgveIps74rS2+Q5aZPJhytXIkmuE+dxMTkV06qGNSYuSurXsoJE7bNfrE/Nmxq6GwKH1rwHXk3c50NoHW/h6/jCXu8x0oY1oW/ea1tLRGY4xeoQ9voCuvVYRFSyuU7Zz2QjlbP+AG8mCnGBxUwqrthqWFe7wDEkYa38EoD9DrjrQKRc4Hn2ZIHYN569cn5PDvsif+5FUX4p+3gEkgk/HVxicC7wT9wYzNSk9HH7bET3V7hnhJ+PJa+ZEH7HAPzry61UZ1gghf4dJAGVE9D8R4/0M6DpKGCQBGXmlI/Q3NjN0jx9NAqffPRxsoW4BF7mLV8RmfDbJJEa0W5i0buwyluMyVcrF5KT9Bd2DBvsULCXfuwwp01DmJdfc=]]></Encrypt>
// </xml>

// decrypt as: <xml><ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
// <FromUserName><![CDATA[oUN420bxqFqlx0ZQHciUOesZO3PE]]></FromUserName>
// <CreateTime>1493212928</CreateTime>
// <MsgType><![CDATA[text]]></MsgType>
// <Content><![CDATA[test]]></Content>
// <MsgId>6413300692136991026</MsgId>
// </xml>
func buildReqWechatPostTxtMsg() *http.Request {
	xml := `<xml>
<ToUserName><![CDATA[gh_f09231355c68]]></ToUserName>
<Encrypt><![CDATA[HKILXQjAOV4Zi5Zb8gQ8zt6EPA6cBCRYSq90PZuyMqZSGhtjMESSgveIps74rS2+Q5aZPJhytXIkmuE+dxMTkV06qGNSYuSurXsoJE7bNfrE/Nmxq6GwKH1rwHXk3c50NoHW/h6/jCXu8x0oY1oW/ea1tLRGY4xeoQ9voCuvVYRFSyuU7Zz2QjlbP+AG8mCnGBxUwqrthqWFe7wDEkYa38EoD9DrjrQKRc4Hn2ZIHYN569cn5PDvsif+5FUX4p+3gEkgk/HVxicC7wT9wYzNSk9HH7bET3V7hnhJ+PJa+ZEH7HAPzry61UZ1gghf4dJAGVE9D8R4/0M6DpKGCQBGXmlI/Q3NjN0jx9NAqffPRxsoW4BF7mLV8RmfDbJJEa0W5i0buwyluMyVcrF5KT9Bd2DBvsULCXfuwwp01DmJdfc=]]></Encrypt>
</xml>`
	b := bytes.NewBufferString(xml)
	req, _ := http.NewRequest("POST", "/api?signature=f06bb28c1d3847815d498fc0a343b11b4d03e095&timestamp=1493212928&nonce=1461107899&openid=oUN420bxqFqlx0ZQHciUOesZO3PE&encrypt_type=aes&msg_signature=61a50d4656b13a7bbeecf53a5a85fbf37835762f", b)
	buildReqCommonHeader(req)

	return req
}

func buildReqWechatWebRoot() *http.Request {
	req, _ := http.NewRequest("GET", "/dummydir", nil)
	buildReqCommonHeader(req)
	q := req.URL.Query()
	//q.Add("signature", "e39de9f2e28079c01ebb4b803dfc3442b819545c")
	q.Add("echostr", "913461463450840893")
	req.URL.RawQuery = q.Encode()
	return req
}

func buildReqWechatAPISetup() *http.Request {
	// Create a request to pass to our handler.
	//We don't have any query body for now, so we'll
	// pass 'nil' as the third parameter.
	req, err := http.NewRequest("GET", "/apii", nil)
	if err != nil {
		log.Fatal(err)
	}

	q := req.URL.Query()
	q.Add("signature", "e39de9f2e28079c01ebb4b803dfc3442b819545c")
	q.Add("echostr", "913461463450840893")
	q.Add("timestamp", "1492970761")
	q.Add("nonce", "1850971833")
	req.URL.RawQuery = q.Encode()

	buildReqCommonHeader(req)
	return req
}

func buildReqCommonHeader(r *http.Request) {
	//
	// example request
	//
	// GET /api?signature=e39de9f2e28079c01ebb4b803dfc3442b819545c&echostr=913461463450840893&timestamp=1492970761&nonce=1850971833 HTTP/1.1
	// Host: wechat.hitxy.org.au
	// Accept: */*
	// Cache-Control: no-cache
	// Connection: Keep-Alive
	// Pragma: no-cache
	// User-Agent: Mozilla/4.0
	// X-Forwarded-For: 103.7.30.107
	// X-Forwarded-Host: wechat.hitxy.org.au
	// X-Forwarded-Server: wechat.hitxy.org.au

	h := r.Header
	h.Set("Host", "wechat.hitxy.org.au")
	h.Set("Accept", "*/*")
	h.Set("Cache-Control", "no-cache")
	h.Set("Connection", "Keep-Alive")
	h.Set("Pragma", "no-cache")
	h.Set("User-Agent", "Patrick testcase")
	h.Set("X-Forwarded-For", "103.7.30.107")
	h.Set("X-Forwarded-Host", "wechat.hitxy.org.au")
	h.Set("X-Forwarded-Server", "wechat.hitxy.org.au")

}
