package utils

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"github.com/sirupsen/logrus"
	"main/database"
	"main/model"
	"reflect"
	"time"
)

func GetPrivateKeys(user string, date string) (model.DayKeys, error) {
	var resKey model.DayKeys
	//today := time.Now().Format("2006-01-02")
	db := database.GetInstance().GetMysqlDb()
	if err := db.Where("date = ? and user = ?", date, user).Order("id").First(&resKey).Error; err != nil {
		logrus.Errorln("sql执行失败：", err)
	}
	if reflect.DeepEqual(resKey, model.DayKeys{}) {
		privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return model.DayKeys{}, err
		}
		x509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
		base64PrivateKey := base64.StdEncoding.EncodeToString(x509PrivateKey)
		resKey = model.DayKeys{
			Date:   date,
			Key:    base64PrivateKey,
			AesKey: NewKey(32),
			User:   user,
		}
		if err1 := db.Create(&resKey).Error; err1 != nil {
			logrus.Errorln("sql执行失败：", err1)
		}
		logrus.Warnln(date + "resKey为空，创建resKey")
		return resKey, nil
	} else {
		if err := db.Where("date = ? and user = ? and id <> ?", date, user, resKey.ID).Delete(&model.DayKeys{}).Error; err != nil {
			logrus.Errorln("sql执行失败：", err)
		}
	}
	logrus.Infoln("resKey存在，返回私钥")
	return resKey, nil
}

func GetPublicKey(user string) (string, error) {
	var userLogin model.User
	db := database.GetInstance().GetMysqlDb()
	if err := db.Where("username = ?", user).First(&userLogin).Error; err != nil {
		logrus.Errorln("sql执行失败：", err)
	}
	if userLogin.Date == "" {
		logrus.Infoln(user + "：用户之前未登录系统")
		userLogin.Date = time.Now().Format("2006-01-02")
	}
	sPrivateKey, err := GetPrivateKeys(user, userLogin.Date)
	if err != nil {
		return "", err
	}
	deBase64privateKey, err := base64.StdEncoding.DecodeString(sPrivateKey.Key)
	if err != nil {
		return "", err
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(deBase64privateKey)
	if err != nil {
		return "", err
	}
	publicKey := privateKey.PublicKey
	x509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	if err != nil {
		return "", err
	}
	base64PublicKey := base64.StdEncoding.EncodeToString(x509PublicKey)
	logrus.Infoln(user + "：获取公钥成功")
	return base64PublicKey, nil
}

func RsaEncrypt(s string, user string) (string, error) {
	sPublicKey, err := GetPublicKey(user)
	if err != nil {
		return "", err
	}
	deBase64Public, err := base64.StdEncoding.DecodeString(sPublicKey)
	if err != nil {
		return "", err
	}
	publicKey, err := x509.ParsePKIXPublicKey(deBase64Public)
	if err != nil {
		return "", err
	}
	res, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.PublicKey), []byte(s))
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(res), nil
}

func RsaDecrypt(s string, sPrivateKey string) (string, error) {
	//sPrivateKey, err := GetPrivateKeys(user)
	//if err != nil {
	//	return "", err
	//}
	deBase64Private, err := base64.StdEncoding.DecodeString(sPrivateKey)
	if err != nil {
		logrus.Errorln("rsa私钥: base64 decode err:", err)
		return "", err
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(deBase64Private)
	if err != nil {
		logrus.Errorln("rsa私钥: x509 decode err:", err)
		return "", err
	}
	des, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		logrus.Errorln("rsa: base64 decode err:", err)
		return "", err
	}
	res, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, des)
	if err != nil {
		logrus.Errorln("rsa: 解密失败:", err)
		return "", err
	}
	return string(res), nil
}
