package com.persagy.revit.services

import com.fasterxml.uuid.Generators
import com.google.common.base.Strings
import com.persagy.database.SFilter
import com.persagy.revit.models.config.MyProperties
import com.persagy.revit.models.jsonAnalyzer.Point
import com.persagy.revit.models.modelFile.FloorModel
import com.persagy.revit.services.http.HttpService
import org.springframework.util.DigestUtils
import java.awt.geom.Area
import java.awt.geom.GeneralPath
import java.awt.geom.Point2D


/**
 *
 *
 * @author jxing
 */
object CommonService {

    /**
     * 生成基于时间的UUID
     */
    fun generateUUID(prefix: String?, isRemoveDash: Boolean): String {
        //        UUID uuid = UUID.randomUUID();
        val uuid = Generators.timeBasedGenerator().generate()
        return arrayOf(Strings.nullToEmpty(prefix), if (isRemoveDash) uuid.toString().replace("-", "") else uuid.toString()).joinToString("")
    }

    /**
     * 获取MD5值
     */
    fun getMD5(btInput : ByteArray) : String {
        return DigestUtils.md5DigestAsHex(btInput)
    }

    /**
     * 获取文件服务器中的文件路径
     */
    fun getFilePathInFileService(uploadPath : String, modelId : String) : String{
        return "${uploadPath}${modelId}.rvt"
    }

    /**
     * 获取文件服务器中的key
     */
    fun getFileKeyInFileService(dir : String, modelId : String) : String{
        return "${dir}/${modelId}.rvt"
    }

    /**
     * 是否点在多边形内
     */
    fun isPointInPolygonCheckWithJdkGeneralPath(point: Point, polygon: ArrayList<Point>): Boolean {
        if(polygon.isEmpty())
            return false
        val p = getGeneralPath(polygon)
        val newPoint = Point2D.Double()
        newPoint.x = point.x
        newPoint.y = point.y
        return p.contains(newPoint)
    }

    /**
     * 是否点在多边形内
     */
    fun isPointInPolygonCheckWithJdkGeneralPath(point: Point2D.Double, polygon: ArrayList<Point2D.Double>): Boolean {
        val p = GeneralPath()
        val first = polygon[0]
        p.moveTo(first.x, first.y)
        polygon.removeAt(0)
        for (d in polygon) {
            p.lineTo(d.x, d.y)
        }
        p.lineTo(first.x, first.y)
        p.closePath()
        return p.contains(point)
    }

    /**
     * 生成bimid前缀
     */
    fun generateBIMIDPrefix(projectId : String, folderId : String, floorName : String, hasColon : Boolean): String{
        if(hasColon){
            return "${projectId}${folderId}${floorName}:"
        }
        return "${projectId}${folderId}${floorName}"
    }

    /**
     * 判断两个多边形 是否重叠
     */
    fun isPolygonOverlap(polygon1 : ArrayList<Point>, polygon2 : ArrayList<Point>) : Boolean{
        if(polygon1.size == 0 || polygon2.size == 0)
            return false
        val p1 = getGeneralPath(polygon1)
        val p2 = getGeneralPath(polygon2)
        val area1 = Area(p1)
        val area2 = Area(p2)
        area1.intersect(area2)
        return !area1.isEmpty
    }

    /**
     * 根据点数组获取围成的GeneralPath对象
     */
    fun getGeneralPath(polygon : ArrayList<Point>) : GeneralPath{
        val p = GeneralPath()
        val first = polygon[0]
        p.moveTo(first.x, first.y)
        for (index in polygon.indices) {
            if(index == 0)
                continue
            val tmpPoint = polygon[index]
            p.lineTo(tmpPoint.x, tmpPoint.y)
        }
        p.lineTo(first.x, first.y)
        p.closePath()
        return p
    }

    /**
     * 获取报告的前缀
     */
    fun getReportPrefix(floor : FloorModel): Pair<String?, String?> {
        val folderArr = BaseDataService.folderService.select(SFilter.eq("id", floor.folderId!!)).exec()
        val folder = folderArr[0]
//        return "${folder.name}的${floor.floorName}"
        return Pair(folder.name, floor.floorName)
    }

    /**
     * 获取CADID信息点
     */
    fun generateCADIDStr(localId: String?, localName: String?): String? {
        val sb = StringBuilder()
        if(!localId.isNullOrBlank()){
            sb.append(localId)
        }
        if(!localName.isNullOrBlank()){
            if(sb.length > 0)
                sb.append(":")
            sb.append(localName)
        }
        return sb.toString()
    }

    /**
     * 根据模型id 获取该模型导出数据jsonz文件的url
     */
    fun getExportJSONDownloadUrl(id: String, myProperties: MyProperties): String {
        return "${myProperties.fileService.exportDownloadPath}${id}.zip"
    }

    /**
     * 获取http远端文件的大小
     */
    fun getRemoteHttpFileSize(url: String): Long {
        var fileLength = -1L
        var retryTimes = 10
        while(retryTimes > 0)
        try {
            var fileLength = HttpService.getFileLength(url)
            if (fileLength >= 0)
                return fileLength
            else
                throw Exception()
        }catch (e : Exception){
            --retryTimes
        }
        return fileLength
    }

    /**
     * 获取异常的堆栈信息
     */
    fun getStackTrace(e : Throwable): String? {
        return org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e)
    }
}