buildscript {
    repositories {
        maven { url 'http://maven.parim.net/nexus/content/groups/public/' }
        mavenCentral()
    }
    dependencies {
        classpath('org.apache.commons:commons-lang3:3.5')
    }
}

project.ext.baseName = 'parim-spark'


import org.apache.commons.lang3.StringUtils

def static String changeStyle(String str, boolean toCamel){
    if(!str || str.size() <= 1)
        return str

    if(toCamel){
        String r = str.toLowerCase().split('_').collect{cc -> StringUtils.capitalize(cc)}.join('')
        return r[0].toLowerCase() + r[1..-1]
    }else{
        str = str[0].toLowerCase() + str[1..-1]
        return str.collect{cc -> ((char)cc).isUpperCase() ? '_' + cc.toLowerCase() : cc}.join('')
    }
}

def static String parseEntity(File entitySouceFile){

    Map<String, String> enumMap = new HashMap<>();

    def classNamePatten = /^.*\/(.+)\.java$/
    def entityPatten = /^@Entity.+"(.*?)".*\)$/
    def tablePatten = /^@Table\(name\s*=\s*"(.*?)".*$/
    def staticPatten = /^.*static.*$/
    def attributePatten = /^\s+private\s+(\S+)\s+(\S+).*;.*$/
    def commentPatten = /^\s+\/*\*+\s*([^@\*\/]*)\s*\**\/*\s*$/
    def joinColumnPatten = /^\s+@JoinColumn\(name\s*=\s*"(.*?)".*$/
    def enumeratedPatten = /^\s+@Enumerated.+$/
    def enumNamePatten = /^\s+public\s+enum\s+([^\s{]+)\s*.*$/
    def enumItemPatten = /^\s+([^,\/\s}]+|[^\/]+)\s*,*.*$/
    def enumEndPatten = /^\s+}.*$/
    def commentEndPatten = /^.*\*\/\s*$/
    def transientPatten = /^\s+@Transient.*$/

    def matching;
    def comment = null;
    def enumItemComment = null;
    def isJoinColumn = false;
    def isEnumStart = false;
    def isEnumerated = false;
    def coloumName;
    def enumName;
    def isTransient = false;
    
    StringBuilder stringBuilder = new StringBuilder("")
    File file = entitySouceFile

    def workDir = System.getProperty("user.dir") + "/"
    def tempFilePath = file.path
    if ('\\' == System.getProperty("file.separator")) {
        workDir = workDir.replaceAll("\\\\","/")
        tempFilePath = file.path.replaceAll("\\\\","/")
    }
    println tempFilePath
    // println workDir
    matching = tempFilePath =~ classNamePatten
    def className = matching[0][1]

    file.eachLine { line -> 
        if (line ==~ tablePatten || line ==~ entityPatten) {
            if (line ==~ tablePatten){
                matching = line =~ tablePatten
            }else{
                matching = line =~ entityPatten
            }
            stringBuilder.append "\n\n## ${matching[0][1].toUpperCase()}\n\n### " + className + "\n"
            if (comment != null) {
                stringBuilder.append "\n${comment}\n\n"
            }
            stringBuilder.append tempFilePath.replace(workDir,'\n')
            stringBuilder.append "\n\n|coloum|type|comment|"
            stringBuilder.append "\n|---|---|---|"
            comment = null
        }
        if ( line ==~ commentPatten) {
            matching = line =~ commentPatten
            // println "--[${comment}]:[${matching[0][1]}]"
            if ('' != matching[0][1]) {
                if ( comment == null ) {
                    comment = matching[0][1]
                } else if (isEnumStart) {
                    enumItemComment = matching[0][1]
                } else {
                    comment += "<br />${matching[0][1]}"
                }
            }
        }
        if ( line ==~ commentEndPatten ) {
            isEnumerated = false
            isJoinColumn = false
        }
        if ( line ==~ enumNamePatten ) {
            matching = line =~ enumNamePatten
            isEnumStart = true
            enumName = matching[0][1]
            /*
            if ( comment == null ) {
                comment = '**枚举值:**'
            } else {
                comment += "<br />**枚举值:**"
            }
            */
            comment = '**枚举值:**'
        }
        if ( isEnumStart && line ==~ enumEndPatten) {
            enumMap.put(enumName, comment)
            isEnumStart = false
            comment = null
        }
        // if ( isEnumStart && !(line ==~ commentPatten) && line ==~ enumItemPatten ) {
        if ( isEnumStart && !(line ==~ commentPatten) && line ==~ enumItemPatten ) {
            matching = line =~ enumItemPatten
            if ('public' != matching[0][1]) {
                if (null != enumItemComment) {
                    comment = "${comment}<br />${matching[0][1]} - ${enumItemComment}"
                    enumItemComment = null;
                } else {
                    comment = "${comment}<br />${matching[0][1]}"
                }
            }
        }
        if ( line ==~ enumeratedPatten ) {
            isEnumerated = true
        }
        if ( line ==~ joinColumnPatten ) {
            matching = line =~ joinColumnPatten
            coloumName = changeStyle(matching[0][1].toLowerCase(),false)
            isJoinColumn = true
        }
        if ( line ==~ transientPatten ) {
            isTransient = true
        }
        if ( !(line ==~ staticPatten) && line ==~ attributePatten) {
            if (isEnumerated){
                matching = line =~ attributePatten
                if (enumMap.get(matching[0][1]) != null) {
                    if (comment != null) {
                        comment = comment + '<br />' + enumMap.get(matching[0][1])
                    } else {
                        comment = enumMap.get(matching[0][1])
                    }
                }
                coloumName = changeStyle(matching[0][2],false)
                stringBuilder.append "\n|${coloumName}|String|${comment?comment:'-'}|"
                comment = null
                isEnumerated = false
            } else if (isJoinColumn){
                matching = line =~ attributePatten
                def fkClassName = matching[0][1]
                comment = "FK : [${fkClassName}](#${fkClassName.toLowerCase()}).id"
                stringBuilder.append "\n|${coloumName}|Long|${comment?comment:'-'}|"
                comment = null
                isJoinColumn = false
            } else if (isTransient) {
                comment = null
                isTransient = false
            } else {
                matching = line =~ attributePatten
                coloumName = changeStyle(matching[0][2],false)
                stringBuilder.append "\n|${coloumName}|${matching[0][1]}|${comment?comment:'-'}|"
                comment = null
            }
        }

    }

    return stringBuilder.toString()
}


task dict {
	doFirst {
	    def versionInfo = "build @ ${new Date().format('yyyy-MM-dd HH:mm:ss')}"
	    def File dictFile = new File("./src/doc/dictionary/data_dictionary.md")
	    if (dictFile.exists()) {
	        dictFile.write('')
	    }
	    dictFile.append("# ${project.baseName} 数据字典 { ignore=true }")
	    dictFile.append("\n\n" + versionInfo)
	    dictFile.append("\n\n## 目录 { ignore=true }")
	    dictFile.append("\n\n[TOC]")
	
	    //以一个基准目录创建一个文件树
	    FileTree tree = fileTree(dir: '.')
	
	    // 添加包含和排除规则
	    tree.include '**/entity/*.java'
	    // tree.exclude '**/Abstract*'
	
	    // 遍历文件树
	    tree.each {File file ->
	        dictFile.append parseEntity(file)
	    }
	}

    // println "\nDefault Charset=" + java.nio.charset.Charset.defaultCharset()
    // println "file.encoding=" + System.getProperty("file.encoding")
    // println "Default Charset in Use=" + (new java.io.OutputStreamWriter(new java.io.ByteArrayOutputStream())).getEncoding(); 

    // println File.separator
    // println System.getProperty("file.separator")
    // dictFile.append parseEntity(new File('spark-survey/survey-provider/src/main/java/net/parim/spark/survey/entity/AsPaper.java'))
    // dictFile.append parseEntity(new File('spark-core/message/src/main/java/net/parim/spark/core/message/entity/MessageBox.java'))
    // dictFile.append parseEntity(new File('spark-core/system-provider/src/main/java/net/parim/spark/core/system/entity/UserGroup.java'))
    // dictFile.append parseEntity(new File('spark-ugc/ugc-provider/src/main/java/net/parim/spark/ugc/chapter/entity/UgcChapter.java'))
    // dictFile.append parseEntity(new File('spark-exam/exam-provider/src/main/java/net/parim/spark/exam/entity/EmDictionaries.java'))
    // dictFile.append parseEntity(new File('spark-learning/learning-provider/src/main/java/net/parim/spark/learning/course/entity/RcoAttempt.java'))
    // dictFile.append parseEntity(new File('spark-core/system-provider/src/main/java/net/parim/spark/core/basis/points/entity/PointsMall.java'))
    // dictFile.append parseEntity(new File('spark-market/market-provider/src/main/java/net/parim/spark/market/entity/Order.java'))

}