package Encryption

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"io"
	"io/ioutil"
	"os"
)

func EncryptData(password string, data []byte) ([]byte, error) {
	var (
		hashedKey  []byte
		ciphertext []byte
		iv         []byte
		block      cipher.Block
		stream     cipher.Stream
		e          error
	)

	hashedKey = CreateHash(password)
	ciphertext = make([]byte, aes.BlockSize+len(hashedKey)+len(data))
	iv = ciphertext[:aes.BlockSize]
	if _, e = io.ReadFull(rand.Reader, iv); e != nil {
		return []byte{}, e
	}
	block, e = CreateKey(hashedKey)
	if e != nil {
		return []byte{}, e
	}
	stream = cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(hashedKey))
	stream.XORKeyStream(ciphertext[aes.BlockSize+len([]byte(hashedKey)):], data)
	return ciphertext, nil
}

func EncryptFile(password string, FilePath string) error {
	var (
		plaintext     []byte
		ciphertext    []byte
		encryptedFile *os.File
		e             error
	)
	plaintext, e = ioutil.ReadFile(FilePath)
	if e != nil {
		return e
	}
	ciphertext, e = EncryptData(password, plaintext)
	if e != nil {
		return e
	}
	// open output file
	encryptedFile, e = os.Create(FilePath + ".enc")
	if e != nil {
		return e
	}

	defer func() {
		encryptedFile.Close()
		SecureDelete(FilePath)
	}()

	_, e = io.Copy(encryptedFile, bytes.NewReader(ciphertext))
	if e != nil {
		return e
	}

	return nil
}
