package model

import (
	//"fmt"
	"time"
	// "math/rand"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

func Init() {
	ConnectDatabase()
	var err error
	// insert auto-table
	err = DB.AutoMigrate(&Content{})
	if err != nil {
		logrus.Fatal(err)
	}
	err = DB.AutoMigrate(&Users{})
	if err != nil {
		logrus.Fatal(err)
	}
	err = DB.AutoMigrate(&Sid{}, &Url{})
	if err != nil {
		logrus.Fatal(err)
	}
}

func ConnectDatabase() {
	// config
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath("./")
	err := viper.ReadInConfig()
	if err != nil {
		logrus.Panic(err)
	}
	// connect to database
	logInfo := viper.GetStringMapString("mysql")
	sqlInfo := logInfo["user"] + ":" + logInfo["password"] +
		"@(localhost)/" + logInfo["database"] + "?charset=utf8mb4&parseTime=True&loc=Local"
	DB, err = gorm.Open(mysql.Open(sqlInfo), &gorm.Config{})
	if err != nil {
		logrus.Panic(err)
	}
}

// Backcheck content through link
// 通过链接反查内容
func Findlink(_url string) string {
	var p Content
	err := DB.First(&p, "Url1 = ?", _url)
	if err != nil {
		logrus.Error(err)
	}
	return p.Route
}

// save text information
// 保存文本和文件信息
func Savetext(_Route string, _Time uint, _Passwd string, _Time1 time.Time, _url string) {
	var id1 int64
	DB.Model(&Content{}).Count(&id1)
	id1++
	p := Content{
		ID:     id1,
		Route:  _Route,
		Time:   _Time,
		Passwd: _Passwd,
		Date:   time.Now(),
		Time1:  _Time1,
		Time2:  0,
		Url1:   _url,
	}
	DB.Create(&p)
}

// Check whether the number of visits exceeds the threshold and the time limit
// 检查是否超过总访问次数和截止时间
func Checkt(p Content) bool {
	t := time.Now()
	p.Time2++
	//fmt.Println(p.Time2)
	if p.Time2 > p.Time || t.After(p.Time1) {
		DB.Delete(&p)
		return true
	}
	DB.Model(&Content{}).Where("Url1 = ?", p.Url1).Update("Time2", p.Time2)
	return false
}

// 这个函数那边有可能需要
// 检查sid是否超时
func Checkt1(sid string) bool {
	var s Sid
	DB.First(&s, "S = ?", sid)
	t := time.Now()
	if t.After(s.Time) {
		return false
	} else {
		return true
	}
}

// 查找sessionid和url是否关联
func Find(sid string, _url string) bool {
	var s Sid
	err1 := DB.First(&s, "S = ?", sid).Error
	//fmt.Println(url.Url1,url.ID,"\n")
	if err1 != nil {
		return false
	}
	var Urls []Url
	DB.Model(&s).Association("Url1").Find(&Urls)
	for _, value := range Urls {
		if value.Url1 == _url {
			return true
		}
	}
	return false
}

//var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789")

/*//*随机生成字符串
func randStr(n int) string {
	rand.Seed(time.Now().Unix())
    b := make([]rune, n)
    for i := range b {
        b[i] = letters[rand.Intn(len(letters))]
    }
    return string(b)
}*/

// 新建用户
func Createuser(_User Users) {
	//_User.SessionId=randStr(8)
	DB.Create(&_User)
}

//新建链接
/* 返回值：
   3 表示sid已经过期，需要重新分配
   2 表示内容过期
   1 表示密码正确
   0 表示密码不正确
*/
func Createlink(sid string, _passwd string, _url string, _Time1 time.Time) uint {
	var p Content
	DB.First(&p, "Url1 = ?", _url)
	if p.Passwd == _passwd {
		if Checkt(p) {
			//fmt.Println(sid,_passwd,_url,_Time1)
			return 2
		}
		var p1 Sid
		err := DB.First(&p1, "S = ?", sid).Error
		if err != nil {
			sid1 := Sid{
				S:    sid,
				Time: _Time1,
				Url1: []Url{
					{Url1: _url},
				},
			}
			DB.Create(&sid1)
		} else {
			t := time.Now()
			if t.After(p1.Time) {
				return 3
			}
			DB.Model(&p1).Association("Url1").Append(&Url{Url1: _url})
		}
		return 1
	}
	return 0
}

// 第一次上传
func CreatelinkFirstTime(sid string, _url string, _Time1 time.Time) {
	sid1 := Sid{
		S:    sid,
		Time: _Time1,
		Url1: []Url{
			{Url1: _url},
		},
	}
	DB.Create(&sid1)
}

/*
func Test() {
	var p Content
	var Url2 string = "1234"
	DB.First(&p, "url1 = ?", Url2)
	fmt.Println(Checkt(p))
}*/
