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
var id1 uint = 0

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) {
	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++
	if p.Time2 > p.Time||t.After(p.Time1) {
		DB.Delete(&p)
		return true
	}
	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 Checkt(p) {
        return 2
	}
	if p.Passwd == _passwd {
		 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 _Createlink(sid string,_url string,_Time1 time.Time) {
	 sid1 := Sid{
		S: sid,
		_Time: _Time1, 
		Url1: []Url{
		  { Url1: _url},
		},
	 }
	 DB.Create(&sid1)
}