//
//  RSAEncryptView.swift
//  GenjiAPITest
//
//

import SwiftUI

struct RSAEncryptView: View {
    
    @Binding var currentDngNr: Int16
    @State private var plainText: String=""
    @State private var encryptedText: String=""
    @State private var currentKeyIndex:Bool = true
    @State private var showPlainEmpty: Bool = false
    
    var body: some View {
                
        Toggle(isOn:$currentKeyIndex) {
            if currentKeyIndex{
                Text("Current key: Key#1")
            }
            else{
                Text("Current key: Key#2")
            }
        }
        
        GroupBox("RSA Encrypt/Decrypt"){
            TextField("PlainText", text: $plainText)
                .padding(.horizontal, 50)
                .onChange(of: plainText) {
                    
                    while plainText.utf8.count > 117 {

                        plainText = String(plainText.prefix(plainText.count-1))
                    }
                }
            
            HStack{
                Button("Encrypt"){
                    
                    if plainText.count==0{
                        showPlainEmpty.toggle( )
                        return
                    }
                    
                    let ptrEncrypted = UnsafeMutablePointer<UInt8>.allocate(capacity: 256)
                    let ptrEncryptedLen = UnsafeMutablePointer<Int16>.allocate(capacity: 1)
                    ptrEncryptedLen[0] = 256
                    
                    
                    if 1 == Dongle_EncryptDataRSA( 1234, currentKeyIndex==true ? 1 : 2, [UInt8](plainText.utf8),
                                                   Int16(plainText.utf8.count), ptrEncrypted, ptrEncryptedLen, currentDngNr,85)
                    {
                        let len = Int16(ptrEncryptedLen.pointee)
                        debugPrint("encrypted len: \(len)")
                        encryptedText.removeAll()
                        
                        for i in 0..<len{
                            encryptedText.append(String(format:"%02x", ptrEncrypted[Int(i)]))
                        }
                        
                        
                        plainText=""
                    }
                    
                    ptrEncrypted.deallocate()
                    ptrEncryptedLen.deallocate()
                    
                }
                .alert("Warning", isPresented: $showPlainEmpty) {
                    // ダイアログ内で行うアクション処理...
                    
                } message: {
                    Text("Plain text empty")
                }
                
                Button("Decrypt"){
                    
                    let enc = RSAEncryptView.hextoUint8Array( hexString:encryptedText )
                    let encLen=enc.count
                    
                    let ptrPlain = UnsafeMutablePointer<UInt8>.allocate(capacity: 256)
                    let ptrPlainLen = UnsafeMutablePointer<Int16>.allocate(capacity: 1)
                    ptrPlainLen[0] = 256
                    
                    if 1 == Dongle_DecryptDataRSA(1234, currentKeyIndex==true ? 1 : 2, enc, Int16(encLen), ptrPlain,ptrPlainLen, currentDngNr,85)
                    {
                        plainText = String(cString: ptrPlain)
                        encryptedText=""
                    }
                    
                    ptrPlain.deallocate()
                    ptrPlainLen.deallocate()
                    
                }
            }
            .padding(.top, 5)
            
            
            TextField("EncryptedText", text: $encryptedText, axis: .vertical)
                .padding(.top, 5)
                .padding(.horizontal, 50)
                .lineLimit(3...5)
        }
    }
    
    static func hextoUint8Array( hexString: String) -> [UInt8] {
        var startIndex=hexString.startIndex
        return stride( from: 0, to: hexString.count, by:2).compactMap {_ in
            let endIndex=hexString.index(startIndex,offsetBy:2, limitedBy: hexString.endIndex) ?? hexString.endIndex
            defer{startIndex = endIndex}
            return UInt8(hexString[startIndex..<endIndex], radix:16)
        }
    }
}

#Preview {
    @Previewable @State var dngNr:Int16 = 0
    RSAEncryptView(currentDngNr: $dngNr)
}
