buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.5.0'
    }
}

plugins {
    id "com.github.hierynomus.license" version "0.14.0"
}

apply plugin: 'com.android.library'
apply plugin: 'checkstyle'

ext.disableCov = project.hasProperty('disableCov') ? project.getProperty('disableCov') : 'false'
if(!disableCov.toBoolean()){
    apply plugin: 'com.vanniktech.android.junit.jacoco'
    junitJacoco {
        excludes = ['com/taobao/weex/dom/flex/**','com/taobao/weex/ui/view/refresh/circlebar/**']
    }
}

task checkstyle(type: Checkstyle) {
    configFile file("${project.rootDir}/sdk/config/quality/checkstyle.xml") // Where my checkstyle config is...
    // configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath // Where is my suppressions file for checkstyle is...
    source 'src'
    include '**/*.java'
    exclude '**/gen/**'
    exclude '**/test/**'
    exclude '**/com/taobao/weex/dom/flex/**'
    classpath = files()
}

checkstyle {
    toolVersion = '6.9'
}


version = "0.18.13.25"

android {

    publishNonDefault true
    compileSdkVersion project.compileSdkVersion
    buildToolsVersion project.buildToolsVersion
    resourcePrefix "weex"

    delete 'libs/armeabi/libweexcore.so'
    delete 'libs/armeabi-v7a/libweexcore.so'
    delete 'libs/x86/libweexcore.so'

    useLibrary 'org.apache.http.legacy'
    copy {
        from '../../pre-build'
        into new File(projectDir,"assets")
        include 'native-bundle-main.js'
        rename('native-bundle-main.js','main.js')
    }
    def line
    new File(projectDir,"assets/main.js").withReader { line = it.readLine() }
    def m = line =~ /[A-Z\s]+\s+([0-9\.]+),\s+Build\s+[0-9]+/;
    def jsfmVersion // = m[0][1]
    println jsfmVersion

    copy {
        from '../../pre-build'
        into new File(projectDir,"assets")
        include 'weex-main-jsfm.js'
        rename('weex-main-jsfm.js','weex-main-jsfm.js')
    }

    copy {
        from '../../pre-build'
        into new File(projectDir,"assets")
        include 'weex-rax-api.js'
    }


//    copy {
//        from '../../pre-build'
//        into new File(projectDir,"assets")
//        include 'weex-rax-extra-api.js'
//    }

    if(project.hasProperty('asfRelease')){
        //download so file if not exist, when compile in source release
        download{
            src 'https://git-wip-us.apache.org/repos/asf?p=incubator-weex.git;a=blob_plain;f=android/sdk/libs/armeabi/libweexcore.so;hb=refs/heads/master'
            dest "${projectDir}/libs/armeabi/libweexcore.so"
            overwrite false
        }
        download{
            src 'https://git-wip-us.apache.org/repos/asf?p=incubator-weex.git;a=blob_plain;f=android/sdk/libs/x86/libweexcore.so;hb=refs/heads/master'
            dest "${projectDir}/libs/x86/libweexcore.so"
            overwrite false
        }
    }

    def ARMEABI_Size = new File(projectDir,"libs/armeabi/libweexcore.so").length();
    def ARMEABIV7_Size = new File(projectDir,"libs/armeabi-v7/libweexcore.so").length();
    def X86_Size = new File(projectDir,"libs/x86/libweexcore.so").length();
    println "ARMEABI_Size: "+ARMEABI_Size;
    println "ARMEABIV7_Size:" + ARMEABIV7_Size;
    println "X86_Size:" + X86_Size;

    defaultConfig {
        buildConfigField "long", "ARMEABI_Size", "${ARMEABI_Size}"
        buildConfigField "long", "ARMEABIV7_Size", "${ARMEABIV7_Size}"
        buildConfigField "long", "X86_Size", "${X86_Size}"
        buildConfigField "String", "buildJavascriptFrameworkVersion", "\"${jsfmVersion}\""
        buildConfigField "String", "buildVersion", "\"${version}\""
        minSdkVersion 14
        targetSdkVersion project.targetSdkVersion

        multiDexEnabled true

        versionCode 1
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a","armeabi","x86"
        }

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_TOOLCHAIN=gcc',
                        '-DANDROID_STL=gnustl_static',
                        '-DCMAKE_BUILD_TYPE=Release'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            testCoverageEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "ENABLE_TRACE", "false"
            consumerProguardFiles 'proguard-rules.pro'
        }

        debug {
            buildConfigField "boolean", "ENABLE_TRACE", "true"
            jniDebuggable true
            debuggable true
            consumerProguardFiles 'proguard-rules.pro'
        }
    }

    externalNativeBuild {
        cmake {
            path '../../weex_core/CMakeLists.txt'
        }
    }

    sourceSets {
        main {
            assets.srcDirs = ['assets']
            jniLibs.srcDir(['libs'])
            java {
                srcDirs = ["src/main/java"];
            }
        }
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }

    compileOptions.encoding = "UTF-8"
    lintOptions {
        abortOnError false
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    testOptions {
        unitTests.all {
            maxHeapSize = "1024m"
            jvmArgs += ['-XX:-UseSplitVerifier', '-noverify','-Xverify:none']/* fix VerifyError  */
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    provided "com.android.support:recyclerview-v7:${project.supportLibVersion}"
    provided "com.android.support:support-v4:${project.supportLibVersion}"
    provided "com.android.support:appcompat-v7:${project.supportLibVersion}"
    provided "com.alibaba:fastjson:${project.fastjsonLibVersion}"

    testCompile "com.alibaba:fastjson:${project.fastjsonLibVersion}"
    testCompile 'junit:junit:4.12'
    testCompile 'org.hamcrest:hamcrest-core:1.3'
    testCompile 'org.javassist:javassist:3.20.0-GA'
    testCompile 'org.mockito:mockito-core:1.10.19'
    testCompile 'org.objenesis:objenesis:2.1'
    testCompile 'org.powermock:powermock-core:1.6.4'
    testCompile 'org.powermock:powermock-api-mockito:1.6.4'
    testCompile 'org.powermock:powermock-module-junit4-common:1.6.4'
    testCompile 'org.powermock:powermock-module-junit4:1.6.4'
    testCompile 'org.powermock:powermock-module-junit4-legacy:1.6.4'
    testCompile 'org.powermock:powermock-module-testng:1.6.4'
    testCompile 'org.powermock:powermock-classloading-xstream:1.6.4'
    testCompile "org.powermock:powermock-module-junit4-rule:1.6.4"
    testCompile 'org.robolectric:robolectric:3.3.2'
    testCompile "org.robolectric:shadows-httpclient:3.3.2"
    testCompile 'org.json:json:20160212'
}

if(file('../license/LICENSE').exists()){
    license {
        header = file('../license/LICENSE')
        mapping('cpp','JAVADOC_STYLE')
        mapping('h','JAVADOC_STYLE')
    }

    task weex_core_license(type: com.hierynomus.gradle.license.tasks.LicenseFormat){
        source = fileTree(dir:"../../weex_core").include(['**/*.h','**/*.cpp', '**/*.cc']).
                exclude(['Source/rapidjson/**/*.h','Source/rapidjson/**/*.cpp',
                         'Source/android/base/base64/**/*.h','Source/android/base/base64/**/*.cpp',
                         'Source/android/jniprebuild/jniheader/*.h',
                         'Source/base/Compatible.cpp',
                         'Source/IPC/**/*.h','Source/IPC/**/*.cpp'])
    }
    preBuild.dependsOn licenseFormat
}
