//
//  TextColorAutoTest.swift
//  KdanAuto
//
//  Created by 朱东勇 on 2022/11/25.
//

import Foundation
import AppKit

class TextColorAutoTest : AutoTest {
    
//    override func type() -> String {
//        return "PDFConvert_Color_Auto_Test"
//    }
    
    override func name() -> String {
        return "字符颜色值转换测试"
    }
    
    override func keys() -> NSArray {
        return ["RGB", "透明度", "快照"]
    }
    
    static var tcSharedInstance = TextColorAutoTest()
    override class func shared() -> AutoTest? {
        return tcSharedInstance
    }
    
    
    // Auto Test refrence Check File
    override func autoTest() {
        clearCacheFiles()
        
        let checkRGB = self.selectedKeys().contains("RGB")
        let checkAlpha = self.selectedKeys().contains("透明度")
        let needCompare = self.selectedKeys().contains("快照")
        
        if !checkRGB && !checkAlpha && !needCompare {
            _status = .Finished
            return
        }
        
        if checkRGB || checkAlpha {
            //需要检测颜色 或 Alpha 值 至少其一
            if checkRGB && checkAlpha {
                reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】识别颜色(转档库暂不支持 Alpha )!\n",
                                                              attributes:[.foregroundColor : NSColor.blue])
            }else if checkRGB {
                reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】识别颜色(不带Alpha )!\n",
                                                              attributes:[.foregroundColor : NSColor.blue])
            }else {
                reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】转档暂不支持 Alpha!\n",
                                                              attributes:[.foregroundColor : NSColor.blue])
                
                if (!needCompare) {
                    _status = .Finished
                    return
                }
            }
        }
        
        _status = .Process
        reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】颜色比对开始!\n",
                                                            attributes:[.foregroundColor : NSColor.blue]))
        let files = DataModel.shared.originFilesFor(_fileType, type: _type)
        
        let checkDirectory = self.checkFileDirectory()
        let originDirectory = self.originFileDirectory()
        let resultDirectory = self.resultFileDirectory()
        
        var tDegree = Double(0);
        var tCount = Int(0)
        
        for fileName in files {
            let fName = NSString(string: fileName).deletingPathExtension
            let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
            let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+_extention)
//            let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+_extention)
            
            
            
            reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】开始转换文件 \"\(fName)\"\n",
                                                          attributes:[.foregroundColor : NSColor.blue]))
            // ...
            // 执行转换过程
            let convertSemaphore = DispatchSemaphore(value: 0)
            var success = false
            let convertQueue = DispatchQueue.global()
            convertQueue.async {
                success = FileConverter.shared().converter(originPath, inDesPath: resultPath)
                
                convertSemaphore.signal()
            }
            convertSemaphore.wait()
            
            
            var maxCount = 0;
            var succCount = 0;
            
            if FileManager.default.fileExists(atPath: resultPath) && success {
                // 转换成功
                if (checkRGB) {
#if true // 新文档框排形式
                    
                    /// 转换结果信息
                    //            let resultData = NSData.init(contentsOfFile: resultPath) as! Data
                    //            var rDocumentAttributes:NSDictionary!
                    //            let resultAttString = NSAttributedString.init(rtf: resultData, documentAttributes: &rDocumentAttributes)
                    //            let resultStr = NSString.init(data: resultData, encoding: 0)
                    let resultString = try? NSString.init(contentsOfFile: resultPath, encoding: 0)
                    
                    // 识别颜色
                    // \colortbl ... }
                    let colorSRange = resultString!.range(of: "\\colortbl")
                    var colorString = resultString!.substring(from: Int(colorSRange.location + colorSRange.length)) as NSString
                    let colorERange = colorString.range(of: "}")
                    colorString = colorString.substring(to: Int(colorERange.location)) as NSString
                    
                    let colorItems = colorString.components(separatedBy: ";") as [String]
                    var colors = NSMutableArray() //存储的颜色数组
                    
                    for ci in colorItems {
                        var colorItem = ci as! NSString
                        if colorItem.length > 0 {
                            colorItem = colorItem.replacingOccurrences(of: "\\red", with: "(") as NSString
                            colorItem = colorItem.replacingOccurrences(of: "\\green", with: ",") as NSString
                            colorItem = colorItem.replacingOccurrences(of: "\\blue", with: ",") as NSString
                            colorItem = colorItem.replacingOccurrences(of: "\\alpha", with: ",") as NSString
                            
                            colors.add(self.colorStringWithString(String(colorItem), withAlpha: false))
                        }
                    }
                    
                    //识别字符串 \shptxt\shptxt ... }
                    let pageInfoStrings = resultString!.components(separatedBy: "\\shptxt\\shptxt")
                    var finalString = ""
                    for pageInfoString in pageInfoStrings {
                        let endRange = NSString(string: pageInfoString).range(of: "}")
                        finalString = finalString.appending(NSString(string: pageInfoString).substring(to: endRange.location))
                    }
                    
                    let oItems = finalString.components(separatedBy: ")") // 用 ) 区分字符段落
                    
                    // 识别
                    for oi in oItems {
                        var oItem = oi as NSString
                        if oItem.contains("[") {
                            oItem = oItem.replacingOccurrences(of: "Color ", with: "Color") as NSString
                            
                            // 识别所有颜色值, 即带 \\s 标准整形值
                            // Detect all color values, those with \\cf tags
                            var cColors = NSMutableArray()
                            var tItem = oItem as NSString
                            while (tItem.contains("\\cf")) {
                                let range = tItem.range(of: "\\cf") as NSRange
                                tItem = tItem.substring(from: Int(range.location + range.length)) as NSString
                                
                                let colorValue = tItem.intValue
                                
                                if !cColors.contains("\(colorValue)") {
                                    cColors.add("\(colorValue)")
                                }
                            }
                            
                            //识别所有 【空格 ~ \】 之间的值，并进行缝合
                            // Detect all strings between Spaces and \ and stitch
                            let strings = oItem.components(separatedBy: " ")
                            var resultStr = "" as NSString
                            for str in strings {
                                let markStr = str as NSString
                                
                                if (markStr.contains("\\")) {
                                    let endRange = markStr.range(of: "\\")
                                    resultStr = resultStr.appending(markStr.substring(to: endRange.location)) as NSString
                                }else {
                                    resultStr = resultStr.appending(markStr as String) as NSString
                                }
                            }
                            
                            // 识别 Mark 值
                            let markRange = resultStr.range(of: "[")
                            let markValue = NSString(string: resultStr.substring(from: Int(markRange.location + markRange.length))).intValue
                            let colorRange = resultStr.range(of: "ColorCheck")
                            let checkColor = self.colorStringWithString(resultStr.substring(from: Int(colorRange.location + colorRange.length)), withAlpha: false)
                            maxCount = maxCount + 1
                            
                            //颜色值对比
                            if cColors.count != 1 || nil == checkColor {
                                reportString?.append(NSAttributedString.init(string: "【\(markValue)】识别颜色出错, 文本识别颜色:\(checkColor) 对照文档颜色:\(cColors)\n",
                                                                             attributes:[.foregroundColor : NSColor.red]))
                                
                                NSLog("\(resultStr):\(cColors)")
                            }else {
                                let colorValue = cColors[0] as! String
                                let detectColor = colors[Int(NSString(string: colorValue).intValue)] as! NSString
                                if detectColor.isEqual(to: checkColor) {
                                    succCount = succCount+1
                                }else {
                                    reportString?.append(NSAttributedString.init(string: "【\(markValue)】识别颜色出错, 文本识别颜色:\(checkColor ?? "") 对照文档颜色:\(detectColor)\n",
                                                                                 attributes:[.foregroundColor : NSColor.red]))
                                    
                                    NSLog("\(resultStr):\(cColors)")
                                    
                                }
                            }
                        }
                    }
                    
#else   // 原富文本形式
        /// 检测信息
                    let resultData = NSData.init(contentsOfFile: resultPath)! as Data
                    var rDocumentAttributes:NSDictionary!
                    let resultAttString = NSAttributedString.init(rtf: resultData, documentAttributes: &rDocumentAttributes)
                    
                    let string = resultAttString?.string
                    
                    
                    var maxCount = 0 as Int
                    var succCount = 0 as Int
                    let semaphore = DispatchSemaphore.init(value: 1)
                    let items = resultAttString!.string.components(separatedBy: "\n")
                    
                    for item in items {
                        let cItem = item as String
                        if NSString(string: cItem).contains("Color Check(") {
                            
                            maxCount = maxCount+1
                            
                            var itemRange = NSString(string: string!).range(of: cItem)
                            let subAttrString = (resultAttString?.attributedSubstring(from: itemRange))! as NSAttributedString
                            
                            let keys = resultAttString?.attributeKeys
                            let attributes = resultAttString?.attributes(at: 1, effectiveRange: &itemRange)
                            
                            NSLog("\(attributes)")
                            
                            let currentString = cItem as! NSString
                            
                            let cColor = subAttrString.at
                            let cColorString = self.colorStringWithColor(cColor, withAlpha: false) as! NSString
                            
                            let dRange = currentString.range(of: "Color Check(") as NSRange
                            let mRange = currentString.range(of: "[") as NSRange
                            let markString = currentString.substring(from: Int(mRange.location+mRange.length)) as! NSString
                            let mark = markString.intValue
                            let dColorString = self.colorStringWithString(currentString.substring(from: Int(dRange.location + dRange.length)), withAlpha: false)! as  NSString
                            
                            if dColorString.isEqual(to: cColorString) {
                                succCount = succCount+1
                            }else {
                                reportString?.append(NSAttributedString.init(string: "【\(mark)】识别颜色出错, 文本识别颜色:\(dColorString) RTF文档颜色:\(cColorString)\n",
                                                                             attributes:[.foregroundColor : NSColor.red]))
                                
                                NSLog("\(item):\(dColorString)")
                                
                            }
                        }
                    }
                    
                    semaphore.wait()
#endif
                    
                    reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"颜色对比完成，准确率\(Float(succCount)/Float(maxCount) * 100)%(\(succCount)/\(maxCount))\n",
                                                                        attributes:[.foregroundColor : NSColor.blue]))
                }
                
                
                if needCompare {
                    reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照生成中\n",
                                                                        attributes:[.foregroundColor : NSColor.black]))
                    let rComparePath = NSString(string: resultDirectory).appendingPathComponent(fName+".jpg")
                    let cComparePath = NSString(string: checkDirectory).appendingPathComponent(fName+".jpg")
                    
                    let processThumbSemaphore = DispatchSemaphore(value: 0)
//                    var processSuccess = false
                    let thumbnailQueue = DispatchQueue.global()
                    thumbnailQueue.async {
//                        processSuccess =
                        if (ProcessThumbnal.process(resultPath, desPath: rComparePath, outputSize: CGSize.init(width: 2048, height: 2048)) &&
                            FileManager.default.fileExists(atPath: rComparePath)) {
                            
                            let degree = self.compareJPEG(rComparePath, checkPath: cComparePath)
                            
                            if degree == -1 {
                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照对比失败，生成快照失败或无比对文件\n",
                                                                                    attributes:[.foregroundColor : NSColor.red]))
                            }else {
                                var color = NSColor.black
                                if fabs(degree-100.0) >= 0.01 {
                                    color = NSColor.red
                                }
                                
                                self._fileDegreeInfo[fileName] = degree
                                tDegree += degree
                                tCount += 1
                                
                                self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照对比完成，图像相似度 \(degree)%\n",
                                                                                    attributes:[.foregroundColor : color]))
                            }
                        }else {
                            self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"快照生成失败\n",
                                                                                attributes:[.foregroundColor : NSColor.red]))
                        }
                        
                        processThumbSemaphore.signal()
                    }
                    processThumbSemaphore.wait()
                    
                }
            }else {
                reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档失败!\n",
                                                              attributes:[.foregroundColor : NSColor.red]))
            }
        }
        
        if tCount != 0 {
            _degree = tDegree / Double(tCount)
        }else {
            _degree = 0
        }
        
        _status = .Finished
    }
    
    // Change String(Red, Green, Blue) to Color
    func colorWithString(_ string:String) -> NSColor? {
        if NSString(string:string).contains(",") {
            let colorItems = NSString(string:string).components(separatedBy: ",")
            if colorItems.count >= 4 {
                return NSColor.init(red: CGFloat(NSString(string: colorItems[0]).intValue)/255.0,
                                    green: CGFloat(NSString(string: colorItems[1]).intValue)/255.0,
                                    blue: CGFloat(NSString(string: colorItems[2]).intValue)/255.0,
                                    alpha: CGFloat(NSString(string: colorItems[3]).intValue)/255.0)
            }else if colorItems.count >= 3 {
                return NSColor.init(red: CGFloat(NSString(string: colorItems[0]).intValue)/255.0,
                                    green: CGFloat(NSString(string: colorItems[1]).intValue)/255.0,
                                    blue: CGFloat(NSString(string: colorItems[2]).intValue)/255.0,
                                    alpha: 1)
            }
        }
        
        return nil
    }
    
    func colorStringWithString(_ string:String, withAlpha:Bool) -> String? {
        if NSString(string:string).contains(",") {
            let colorItems = NSString(string:string).components(separatedBy: ",")
            if colorItems.count >= 4 && withAlpha {
                return String("(\(NSString(string: colorItems[0]).intValue),\(NSString(string: colorItems[1]).intValue),\(NSString(string: colorItems[2]).intValue),\(NSString(string: colorItems[3]).intValue))")
            }else if colorItems.count >= 3 {
                if withAlpha {
                    return String("(\(NSString(string: colorItems[0]).intValue),\(NSString(string: colorItems[1]).intValue),\(NSString(string: colorItems[2]).intValue),255)")
                }else {
                    return String("(\(NSString(string: colorItems[0]).intValue),\(NSString(string: colorItems[1]).intValue),\(NSString(string: colorItems[2]).intValue))")
                }
            }
        }
        
        return nil
    }
    
    func colorStringWithColor(_ color:NSColor, withAlpha:Bool) -> String? {
        if color != nil {
            let red = Int(color.redComponent * 255)
            let green = Int(color.greenComponent * 255)
            let blue = Int(color.blueComponent * 255)
            let alpha = Int(color.alphaComponent * 255)
            
            if withAlpha {
                return String("(\(red),\(green),\(blue),\(alpha)")
            }else {
                return String("(\(red),\(green),\(blue)")
            }
        }
        
        return nil
    }
    
    //
}
