package cn.sagacloud.server.algorithm.services.excel

import com.alibaba.fastjson.JSON
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.springframework.context.annotation.Scope
import org.springframework.stereotype.Component
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ByteArrayInputStream
import java.io.ObjectOutputStream
import java.io.Serializable





/**
 * excel 报告模板
 */
@Component
@Scope("prototype")
class ExcelTemplate {

    private val lock = Any()
    private var workBook: XSSFWorkbook? = null

    fun getExcel2007Template(excelName : String): XSSFWorkbook? {
        try {
            val inputStream = ExcelTemplate::class.java.classLoader.getResourceAsStream(excelName)
            workBook = XSSFWorkbook(inputStream)
            return workBook
        } catch (e: Exception) {
            e.printStackTrace()
            println("exception: ${e.message}")
            return null
        }
    }

    fun getExcel2007TemplateSingleton(): XSSFWorkbook? {
        try {
            if (workBook == null) {
                synchronized(lock) {
                    if (workBook == null) {
                        val inputStream = ExcelTemplate::class.java.classLoader.getResourceAsStream("data_check.xlsx")
                        workBook = XSSFWorkbook(inputStream)
                    }
                }
            }
            return workBook
        } catch (e: Exception) {
            e.printStackTrace()
            println("exception: ${e.message}")
            return null
        }
    }

    fun getExcelCopy() : XSSFWorkbook?{
        var template = getExcel2007Template("data_check.xlsx")
        var jsonStr = JSON.toJSONString(template)
        var copy = JSON.toJavaObject(JSON.parseObject(jsonStr), XSSFWorkbook::class.java)
        return copy
    }

    fun <T : Serializable> clone(obj: T): T? {
        var cloneObj: T? = null
        var oos: ObjectOutputStream? = null
        var ois: ObjectInputStream? = null
        try {
            val baos = ByteArrayOutputStream()
            oos = ObjectOutputStream(baos)
            oos.writeObject(obj)

            val bais = ByteArrayInputStream(baos.toByteArray())
            ois = ObjectInputStream(bais)
            cloneObj = ois.readObject() as T
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            if (oos != null) {
                try {
                    oos.close()
                } catch (e: Exception) {
                    e.printStackTrace()
                }

            }
            if (ois != null) {
                try {
                    ois.close()
                } catch (e: Exception) {
                    e.printStackTrace()
                }

            }
        }
        return cloneObj
    }
}
