package session

import (
	"testing"
	"ddpf/model/dbm"
	"time"
	"github.com/tangs-drm/go-tool/log"
	"fmt"
	"github.com/tangs-drm/go-tool/util"
	"github.com/tangs-drm/go-tool/http"
	ghttp "net/http"
	"io/ioutil"
	"ddpf/test"
)

func init() {
	test.SqlConf = "../../../ddpf.sql"
	test.Init()
}

// TestSession 对session的单元测试
func TestSession(t *testing.T) {
	log.Debug("TestSession --- START")

	fmt.Println(time.Now().Unix())
	fmt.Println(time.Now().UnixNano())

	fmt.Println(util.Now())
	fmt.Println(util.Now10())
	fmt.Println(util.Now13())

	var uid string = "u100"
	session, err := CreateSession(uid)
	if err != nil {
		t.Error(err)
		return
	}
	if len(session.Id) < 1 || session.Uid != uid {
		t.Error(session.Id, session.Uid)
		return
	}
	if session.Time > 10000000001 || session.LastTime > 10000000001 {
		t.Error(session.Time, session.LastTime)
		return
	}

	Valid_Session_Time = 5
	valid, err := CheckValidSession(session.Id)
	if err != nil {
		t.Error(err)
		return
	}
	if !valid {
		t.Error(valid)
		return
	}

	time.Sleep(10*time.Second)
	valid, err = CheckValidSession(session.Id)
	if err != nil {
		t.Error(err)
		return
	}
	if valid {
		t.Error(valid)
		return
	}

	// flushSession
	FlushSession(session.Id)
	valid, err = CheckValidSession(session.Id)
	if err != nil {
		t.Error(err)
		return
	}
	if !valid {
		t.Error(valid)
		return
	}
	log.Debug("TestSession --- END")
}

func HaloHandleFunc(w ghttp.ResponseWriter, r *ghttp.Request) {
	fmt.Println("HaloHandleFunc come in")
	w.Write([]byte("halo"))
	return
}

func RootHandleFunc(w ghttp.ResponseWriter, r *ghttp.Request) {
	fmt.Println("RootHandleFunc come in")
	w.Write([]byte("root"))
}

func TestUserFilter(t *testing.T) {
	var times int = 10
	for i := 0; i < times; i ++ {
		testUserFilter(t, i)
	}
	log.Debug("TestUserFilter 测试完毕")
}

func testUserFilter(t *testing.T, times int) {
	log.Debug("testUserFiler times(%v) --- START", times)
	SessionLog = true
	mux := http.NewServerMux()
	mux.HandleFunc("/", RootHandleFunc)
	mux.FilterFunc("/usr", UserFilterFunc)
	//mux.HandleFunc("/login", RootHandleFunc)
	mux.HandleFunc("/usr/halo", HaloHandleFunc)

	go func() {
		log.Error("%v", ghttp.ListenAndServe(":8023", mux))
	}()

	//time.Sleep(2 * time.Second)

	resString, err := util.HTTPGetString("http://127.0.0.1:8023/usr/halo")
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Println(resString)

	// 设置session
	session, err := CreateSession("u101")
	if err != nil {
		t.Error(err)
		return
	}

	// 带上cookie的请求
	req, err := ghttp.NewRequest("GET", "http://127.0.0.1:8023/usr/halo", nil)
	if err != nil {
		t.Error(err)
		return
	}
	cookie := &ghttp.Cookie{
		Domain:"/",
		Name:"token",
		Value:session.Id,
	}
	req.AddCookie(cookie)
	client := ghttp.Client{}
	resp, err := client.Do(req)
	if err != nil {
		t.Error(err)
		return
	}
	bys, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Error(err)
		return
	}
	if string(bys) != "halo" {
		t.Error(string(bys))
		return
	}

	// 错误的cookie请求，被重定向到/
	req, err = ghttp.NewRequest("GET", "http://127.0.0.1:8023/usr/halo", nil)
	if err != nil {
		t.Error(err)
		return
	}
	cookie = &ghttp.Cookie{
		Domain:"/",
		Name:"token",
		Value:util.UUID(),
	}
	req.AddCookie(cookie)
	client = ghttp.Client{}
	resp, err = client.Do(req)
	if err != nil {
		t.Error(err)
		return
	}
	bys, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Error(err)
		return
	}
	if string(bys) != "root" {
		t.Error(string(bys))
		return
	}

	// 查看sessiond的时间更新
	now := util.Now10()
	req, err = ghttp.NewRequest("GET", "http://127.0.0.1:8023/usr/halo", nil)
	if err != nil {
		t.Error(err)
		return
	}
	cookie = &ghttp.Cookie{
		Domain:"/",
		Name:"token",
		Value:session.Id,
	}
	req.AddCookie(cookie)
	client = ghttp.Client{}
	resp, err = client.Do(req)
	if err != nil {
		t.Error(err)
		return
	}
	bys, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Error(err)
		return
	}
	if string(bys) != "halo" {
		t.Error(string(bys))
		return
	}
	// check session
	rows, err := dbm.Db().Query("SELECT LASTTIME FROM SESSION WHERE ID = ? ORDER BY LASTTIME DESC;", session.Id)
	if err != nil {
		t.Error(err)
		return
	}
	var sessionNow int64
	for rows.Next() {
		err = rows.Scan(&sessionNow)
		if err != nil {
			t.Error(err)
			return
		}
		break
	}
	log.Debug("TestUserFilter get lastTime (%v), now (%v)", sessionNow, now)
	if sessionNow < now {
		t.Error(sessionNow)
		return
	}

	log.Debug("testUserFilter times(%v) --- END", times)
}