package common

import (
	"bytes"
	"crypto/sha256"
	"dbweb/core"
	"dbweb/lib/safe"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/linlexing/dbx/data"
)

type Login struct{}

func (m *Login) Get(p *core.ElementHandleArgs) {
	//退出系统
	if p.Element.Name == "logout" {
		p.LSession.Clear()
		p.Redirect("/login")
		return
	}
	q := p.Req.URL.Query()
	//检查用户是否存在
	if q.Get("a") == "cu" {
		var iCount int64
		if err := p.DB.QueryRow("select count(*) from NUSER where name=?", p.Req.URL.Query().Get("u")).
			Scan(&iCount); err != nil {
			core.LOG.Panic(err)
		}
		p.Render.JSON(http.StatusOK, map[string]interface{}{
			"check": iCount > 0})
		return
	}
	if q.Get("a") == "silence" {
		if err := m.login(p, q.Get("uname"), q.Get("pwd")); err != nil {
			p.RenderError(err.Error())
		}
		//如果有附加参数，则存贮到session中

		if tag := q["tag"]; len(tag) > 0 {
			p.LSession.Set("FromCallTag", tag)
		}
		return
	}
	p.HTML()
}
func (m *Login) login(p *core.ElementHandleArgs, userName, password string) error {
	t, err := data.OpenTable(p.DB.DriverName(), p.DB, "NUSER")
	if err != nil {
		return err
	}
	user, err := t.Row(userName)
	if err != nil {
		return err
	}
	if user == nil {
		return fmt.Errorf("用户名错误")
	}
	pwd1 := sha256.Sum256(append(safe.Bytea(user["SALT"]), []byte(password)...))

	pwd, err := BuildUserPassword(password, safe.Bytea(user["SALT"]))
	if err != nil {
		return err
	}
	if bytes.Equal(pwd1[:], safe.Bytea(user["PASSWORD"])) ||
		bytes.Equal(pwd, safe.Bytea(user["PASSWORD"])) {
		dt, err := data.OpenTable(p.DB.DriverName(), p.DB, "DEPT")
		if err != nil {
			return err
		}
		dept, err := dt.Row(user["DEPT"])
		if err != nil {
			return err
		}
		if dept == nil {
			return fmt.Errorf("用户名所属部门代码:%s无效", user["DEPT"])
		}
		if user["FREEZETIME"] != nil {
			ftime := safe.Date(user["FREEZETIME"])

			if ftime.After(time.Now()) {
				return fmt.Errorf("你已经被冻结，还有 %s 到期,原因:\n%s",
					time.Until(ftime).String(), safe.String(user["FREEZEDESC"]))
			}
		}
		newUser := core.NewUser(p.DB, userName)
		p.LSession.Set("$user", newUser)
		p.User = newUser
		core.CallSystemLoginEvent(p)
		indexElement := "index"
		if o := core.GetOption(p.DB, "IndexElement"); len(o) > 0 {
			indexElement = o
		}
		if next := p.Req.URL.Query().Get("next"); next != "" {
			p.Redirect(next)
		} else {
			p.Redirect(newUser.Sign("/" + indexElement))
		}
		return nil
	} else {
		log.Printf("pwd error ,db:%x,input:%x\n", safe.Bytea(user["PASSWORD"]), pwd[:])
		return fmt.Errorf("密码错误")
	}
}
func (m *Login) Post(p *core.ElementHandleArgs) {
	if err := p.Req.ParseForm(); err != nil {
		core.LOG.Panic(err)
	}
	userName := p.Req.FormValue("userName")
	if err := m.login(p, userName, p.Req.FormValue("password")); err != nil {
		p.More["Error"] = err.Error()
		p.HTML()
	}
	return
}
