package auth

import (
	"errors"
	"os"
	"time"

	"github.com/golang-jwt/jwt"
	log "github.com/sirupsen/logrus"
	"golang.org/x/crypto/bcrypt"
)

var secretKey []byte

func Setup() {
	secretKeyString, isSet := os.LookupEnv("SECRET_KEY")
	if !isSet {
		log.Warn("SECRET_KEY not set in environment, using default key")
		secretKeyString = "DebugKey"
	}

	secretKey = []byte(secretKeyString)
}

func makePasswordSalty(password string, salt []byte) []byte {
	passwordBytes := []byte(password)
	passwordBytes = append(passwordBytes, salt...)
	return passwordBytes
}

func HashPassword(password string, salt []byte) (hashedPassword []byte, err error) {
	saltyPassword := makePasswordSalty(password, salt)
	hashedPassword, err = bcrypt.GenerateFromPassword(saltyPassword, bcrypt.DefaultCost)
	return
}

func CheckPassword(password string, salt []byte, hashedPassword []byte) (err error) {
	saltyPassword := makePasswordSalty(password, salt)
	err = bcrypt.CompareHashAndPassword(hashedPassword, saltyPassword)
	return
}

func GenerateJWT(id uint, username string, email string) (jwttoken string, err error) {
	token := jwt.New(jwt.SigningMethodHS256)
	claims := token.Claims.(jwt.MapClaims)

	claims["authorized"] = true
	claims["user_id"] = id
	claims["username"] = username
	claims["email"] = email
	claims["exp"] = time.Now().Add(time.Hour * 2).Unix()

	if jwttoken, err = token.SignedString(secretKey); err != nil {
		log.Errorf("Something Went Wrong: %s", err.Error())
	}
	return
}

func VerifyJWT(jwttoken string) (claims jwt.MapClaims, err error) {
	token, e := jwt.ParseWithClaims(jwttoken, &jwt.MapClaims{}, func(t *jwt.Token) (interface{}, error) {
		return secretKey, nil
	})
	if e != nil || !token.Valid {
		err = errors.New("Unautherized")
		return
	}
	claimsptr := token.Claims.(*jwt.MapClaims)
	claims = *claimsptr
	return
}
