 import Security
 
 
+//
+//  Encrypt.swift
+//  Surf
+//
+//  Created by yarshure on 16/5/12.
+//  Copyright © 2016年 yarshure. All rights reserved.
+//
+// gfw.press support
+import Foundation
+import Security
+
+
 //let kChosenCipherBlockSize = kCCBlockSizeAES128
 //let kChosenCipherKeySize = kCCKeySizeAES128
 //import CryptoSwift

                //NSString* cipherFinalDecrypt = [[NSString alloc] initWithData:cipherDataDecrypt encoding:NSUTF8StringEncoding];
                
                //Final Cryptor
                let final:CCCryptorStatus = CCCryptorFinal(cryptor, //CCCryptorRef cryptorRef,
                    cipherDataDecrypt.mutableBytes, //void *dataOut,
                    cipherDataDecrypt.length, // size_t dataOutAvailable,
                    &outLengthDecrypt); // size_t *dataOutMoved)
                
                if (final == CCCryptorStatus( kCCSuccess))
                {
                    //Release Cryptor
                    //CCCryptorStatus release =
                    CCCryptorRelease(cryptor); //CCCryptorRef cryptorRef
                }
                
                return cipherDataDecrypt ;//cipherFinalDecrypt;
            }
        }

        return nil
    }

        // Init cryptor
        
        //Empty IV: initialization vector
        
        
        var used_Length:Int = 0
        if ivBuffer.length  == 0 {
            //有没用没解完的，有先解
            let result = NSMutableData.init()
            if leftdataLength > 0  {
                
                
                if recv_iv == nil {
                    AxLogger.log("recv_iv check fail",level: .Debug)
                }
                
                var length:Int = 0
                var touse:NSData
                if leftdataLength >= encrypt_bytes.length {
                    length = encrypt_bytes.length
                }else {
                    length = leftdataLength
                }
                
                touse = encrypt_bytes.subdataWithRange(NSMakeRange(0,length))
                
                let r0 = decrypt(ramdonKey!, encrypt_bytes:touse , iv: recv_iv!)
                
                
                leftdataLength -= length
                used_Length += length
                
                if leftdataLength == 0 {
                    AxLogger.log("packet decrypt fin clear iv",level: .Debug)
                    recv_iv = nil
                    //recv_ctx?.ctx = nil // reset ctx
                    CCCryptorRelease((recv_ctx?.ctx)!);
                }
                
                
                if used_Length  == encrypt_bytes.length {
                    //正好全部解完
                    return r0
                }else {
                    result.appendData(r0!)
                }
                //let iv:NSData =  encrypt_bytes.subdataWithRange(NSMakeRange(0,m.iv_size))
            }
            
            if lettnoiseLength > 0 {
                let left = encrypt_bytes.length - used_Length
                if left >= lettnoiseLength{
                    
                    used_Length += lettnoiseLength
                    lettnoiseLength -= lettnoiseLength
                }else {
                    used_Length += left
                    lettnoiseLength -= left
                    return result
                }
                
            }
            //是否还有packet 需要解?
            let  left = encrypt_bytes.length - used_Length
            if left > 0 {
                
                let leftdata = encrypt_bytes.subdataWithRange(NSMakeRange(used_Length,encrypt_bytes.length - used_Length))
                
                if let r2 =  descrypt(ramdonKey!, encrypt_bytes_pre: leftdata) {
                    result.appendData(r2)
                }
                return result
            }else {
                //解完了
                return result
            }
            

        }else {
            if leftdataLength > 0 || lettnoiseLength > 0  {
                
                AxLogger.log("ivBuffer error",level:  .Error)
                
            }
            
            ivBuffer.appendData(encrypt_bytes)
            if let r = descrypt(key,encrypt_bytes_pre:ivBuffer){
                return r
            }
            return nil

        }
        

        
        
                //return nil
    }
    func descrypt(key:NSData,encrypt_bytes_pre:NSData) ->NSData?{
        //可能有多个加密包
        //if encrypt_bytes.length < Encrypt.ENCRYPT_SIZE{
        //    ivBuffer.appendData(encrypt_bytes)
        //}
        var used_length = 0
        let total_len = encrypt_bytes_pre.length
        var result = NSMutableData.init()
        while used_length <=  total_len {
            if total_len < Encrypt.ENCRYPT_SIZE {
                ivBuffer.setData(encrypt_bytes_pre)
                return nil
            }
            var tempData = encrypt_bytes_pre.subdataWithRange(NSMakeRange(0, Encrypt.ENCRYPT_SIZE))
            used_length += Encrypt.ENCRYPT_SIZE
            let sizes = getBlockSizes(tempData)
            if sizes.count != 2 {
                AxLogger.log("data size and noise size error",level:  .Error)
            }else {
                leftdataLength = sizes[0]
                lettnoiseLength  = sizes[1]
                AxLogger.log("data size:\(leftdataLength) and noise size: \(lettnoiseLength)",level:  .Debug)
            }
            
            if used_length + m.iv_size < total_len{
                tempData = encrypt_bytes_pre.subdataWithRange(NSMakeRange(used_length,total_len - used_length))
                ivBuffer.setData(tempData)
                return nil
            }else {
                tempData = encrypt_bytes_pre.subdataWithRange(NSMakeRange(used_length,m.iv_size))
                used_length += m.iv_size
            }
            recv_iv = tempData //初始化IV
            
            if used_length + leftdataLength <= total_len {
                //enough 
                tempData = encrypt_bytes_pre.subdataWithRange(NSMakeRange(used_length,leftdataLength))
                used_length += leftdataLength
                leftdataLength = 0
            }else {
                tempData = encrypt_bytes_pre.subdataWithRange(NSMakeRange(used_length,total_len - used_length))
                used_length += total_len - used_length
                leftdataLength -= total_len - used_length
            }
            
            if let t = decrypt(key, encrypt_bytes: tempData, iv: recv_iv!){
                result.appendData(t)
                
            }
            
            if leftdataLength == 0 {
                recv_iv = nil
                //recv_ctx?.ctx = nil // reset ctx
                CCCryptorRelease((recv_ctx?.ctx)!)
                
                let l_len = total_len - used_length
                //left len
                
                if lettnoiseLength <= l_len {
                    lettnoiseLength = 0
                    used_length += lettnoiseLength
                }else {
                    lettnoiseLength -= l_len
                    used_length += l_len
                }
                
            }else {
                // > 0 
                return result
            }
            //var left_length = total_len - used_length
            
        }
        
        
        
       
        
//        let iv:NSData =  encrypt_bytes.subdataWithRange(NSMakeRange(used_Length,m.iv_size))
//        used_Length += m.iv_size
//        let left:NSData = encrypt_bytes.subdataWithRange(NSMakeRange(used_Length,encrypt_bytes.length - used_Length))
//
//        let iv:NSData =  encrypt_bytes.subdataWithRange(NSMakeRange(used_Length,m.iv_size))
//        used_Length += m.iv_size
//        let left:NSData = encrypt_bytes.subdataWithRange(NSMakeRange(used_Length,encrypt_bytes.length - used_Length))
//        let r2 =  decrypt(ramdonKey!, encrypt_bytes:left , iv: iv)
//        result.appendData(r2!)
//        return r2
        return result
        
    }
    /**
     * 解密
