import { CommonSync, sm4Sync,ivSync,sm2Validate } from '../interface.uts';
import { Insecure, SHA256 } from 'CryptoKit';
import { AES, ECB, CBC } from "CryptoSwift";
import { GMSm3Utils, GMSm4Utils, GMSm2Utils } from "GMObjC";
import { PublicKey, ClearMessage, EncryptedMessage } from "SwiftyRSA";

// md5加密
export const md5Sync : CommonSync = function (md5Str : string) : string {
	let data = md5Str.data(using = String.Encoding.utf8)!
	let MD5Digest = Insecure.MD5.hash(data = data)
	let ht = MD5Digest.map((x : UInt8) : String => {
		let str = String(format = "%02hhx", x)
		if (str != nil) {
			return str;
		} else {
			return "";
		}
	})
	return ht.join('');
}

// base64加密
export const base64EncodeSync : CommonSync = function (str : string) : string {
	const originalData = str.data(using = String.Encoding.utf8)!
	const base64EncodedString = originalData.base64EncodedString()
	return base64EncodedString;
}

// base64解密
export const base64DecodeSync : CommonSync = function (str : string) : string {
	let decodedData = Data(base64Encoded = str)!
	if (decodedData != nil) {
		let originalString = String(data = decodedData, encoding = String.Encoding.utf8)!
		if (originalString != nil) {
			return originalString
		} else {
			return "";
		}
	} else {
		return "";
	}
}

// SHA1加密
export const sha1Sync : CommonSync = function (str : string) : string {
	let data = str.data(using = String.Encoding.utf8)!
	let SHA1Digest = Insecure.SHA1.hash(data = data)
	let ht = SHA1Digest.map((x : UInt8) : String => {
		let str = String(format = "%02hhx", x)
		if (str != nil) {
			return str;
		} else {
			return "";
		}
	})
	return ht.join('');
}

// SHA256加密
export const sha256Sync : CommonSync = function (str : string) : string {
	let data = str.data(using = String.Encoding.utf8)!
	let SHA256Digest = SHA256.hash(data = data)
	let ht = SHA256Digest.map((x : UInt8) : String => {
		let str = String(format = "%02hhx", x)
		if (str != nil) {
			return str;
		} else {
			return "";
		}
	})
	return ht.join('');
}

// AES对称加密
export const aesEncryptSync : sm4Sync = function (plainText : string, key : string) : string {
	let keyData = key.data(using = String.Encoding.utf8)!
	let plainTextData = plainText.data(using = String.Encoding.utf8)!
	try {
		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = ECB(), padding = Padding.pkcs7))
		// 开始加密
		let encrypted = UTSiOS.try(aes.encrypt(plainTextData.bytes))
		// 将加密结果转成base64形式
		return encrypted.toBase64()
	} catch (e) {
		console.log(e);
		return "";
	}
}

// AES对称解密
export const aesDecryptSync : sm4Sync = function (encryptedBase64 : string, key : string) : string {
	let keyData = key.data(using = String.Encoding.utf8)!

	try {
		let encryptedData = Data(base64Encoded = encryptedBase64)!
		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = ECB(), padding = Padding.pkcs7))
		// 开始加密
		let decryptedBytes = UTSiOS.try(aes.decrypt(encryptedData.bytes))
		let decryptedData = Data(decryptedBytes)
		let decryptedString = String(data = decryptedData, encoding = String.Encoding.utf8)!
		if (decryptedString != nil) {
			return decryptedString
		} else{
			return "";
		}
	} catch (e) {
		console.log(e);
		return "";
	}
}

// 国产SM3加密
export const sm3EncryptSync : CommonSync = function (dataString : string) : string {
	let plainData = dataString.data(using = String.Encoding.utf8)!
	let res = GMSm3Utils.hash(with = plainData)!
	return res;
}

// 国产SM4ECB加密
export const sm4ECBEncryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
	let res = GMSm4Utils.ecbEncryptText(dataString,key=keySM4)!
	return res;
}

// 国产SM4ECB解密
export const sm4ECBDecryptSync : sm4Sync = function (dataString : string, keySM4 : string) : string {
	let res = GMSm4Utils.ecbDecryptText(dataString,key=keySM4)!
	return res;
}

// 国产SM4CBC加密
export const sm4CBCEncryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
	let res = GMSm4Utils.cbcEncryptText(dataString,key=keySM4,iv=iv)!
	return res;
}

// 国产SM4CBC解密
export const sm4CBCDecryptSync : ivSync = function (dataString : string, keySM4 : string, iv: string) : string {
	let res = GMSm4Utils.cbcDecryptText(dataString,key=keySM4,iv=iv)!
	return res;
}

// 国产SM2非对称公钥加密
export const sm2EncryptSync : sm4Sync = function (dataString : string, publicKey : string) : string {
	let res = GMSm2Utils.encryptText(dataString,publicKey=publicKey)!
	return res;
}

// 国产SM2非对称私钥解密
export const sm2DecryptSync : sm4Sync = function (dataString : string, privateKey : string) : string {
	let res = GMSm2Utils.decrypt(toText=dataString,privateKey=privateKey)!
	return res;
}

// sm2签名
export const sm2PubSignSync : sm4Sync = function (dataString : string, privateKey : string) : string {
	const sign = GMSm2Utils.signText(dataString, privateKey=privateKey, userID=nil)!;
	return sign;
}
// sm2验签
export const sm2PubSignValSync : sm2Validate = function (dataString : string, publicKey : string, sign : string) : boolean {
	const verifySign = GMSm2Utils.verifyText(dataString, signRS=sign, publicKey=publicKey, userID=nil);
	return verifySign;
}

// hmacSHA1加密
export const hmacSHA1Sync : sm4Sync = function (plaintext : string, key : string) : string {
	let res = GMSm3Utils.hmac(GMHashType.SHA1 ,key=key,plaintext=plaintext)!
	return res;
}

// AES CBC对称加密
export const aesCBCEncryptSync : ivSync = function (plainText : string, key : string, iv: string) : string {
	let keyData = key.data(using = String.Encoding.utf8)!
	let ivData = iv.data(using = String.Encoding.utf8)!
	let plainTextData = plainText.data(using = String.Encoding.utf8)!
	try {
		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = CBC(iv=ivData.bytes), padding = Padding.pkcs7))
		// 开始加密
		let encrypted = UTSiOS.try(aes.encrypt(plainTextData.bytes))
		// 将加密结果转成base64形式
		return encrypted.toBase64()
	} catch (e) {
		console.log(e);
		return "";
	}
}

// AES CBC对称解密
export const aesCBCDecryptSync : ivSync = function (encryptedBase64 : string, key : string, iv: string) : string {
	let keyData = key.data(using = String.Encoding.utf8)!
	let ivData = iv.data(using = String.Encoding.utf8)!
	
	try {
		let encryptedData = Data(base64Encoded = encryptedBase64)!
		let aes = UTSiOS.try(AES(key = keyData.bytes, blockMode = CBC(iv=ivData.bytes), padding = Padding.pkcs7))
		// 开始加密
		let decryptedBytes = UTSiOS.try(aes.decrypt(encryptedData.bytes))
		let decryptedData = Data(decryptedBytes)
		let decryptedString = String(data = decryptedData, encoding = String.Encoding.utf8)!
		if (decryptedString != nil) {
			return decryptedString
		} else{
			return "";
		}
	} catch (e) {
		console.log(e);
		return "";
	}
}

// RSA非对称加密
export const rsaEncryptSync : sm4Sync = function (dataString : string, publicStr: string) : string {
	try {
		let publicKey = UTSiOS.try(PublicKey(pemEncoded = publicStr))
		let clear = UTSiOS.try(ClearMessage(string = dataString, using = String.Encoding.utf8))
		let encrypted = UTSiOS.try(clear.encrypted(with = publicKey, padding = Padding.PKCS1))
		return encrypted.base64String
	} catch (e) {
		console.log(e);
		return "";
	}
}

// RSA非对称解密
export const rsaDecryptSync : sm4Sync = function (dataString : string, privateStr: string) : string {
	try {
		let privateKey = UTSiOS.try(PrivateKey(pemEncoded = privateStr))
		let encrypted = UTSiOS.try(EncryptedMessage(base64Encoded = dataString))
		let clear = UTSiOS.try(encrypted.decrypted(with = privateKey, padding = Padding.PKCS1))
		let base64String = clear.base64String
		return base64DecodeSync(base64String)
	} catch (e) {
		console.log(e);
		return "";
	}
}