/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

buildscript {
    repositories {
        mavenLocal()
        maven {url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        if(!project.disableCov) {
            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'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'com.github.dcendents.android-maven'

if(!project.disableCov){
    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 = project.hasProperty('weexVersion') ? project.getProperty('weexVersion') : "0.24.0.1"

//Check version, the version must have 4 sections. The leading three section must be number, and the last section is odd number with or without suffix string.
if (!project.hasProperty('ignoreVersionCheck') || !project.getProperty('ignoreVersionCheck').equals("true")) {
    assert version.tokenize('.').eachWithIndex { it, i ->
        if (i < 3) {
            assert it.isNumber()
        } else if (i == 3) {
            it.split("-|_").toList().eachWithIndex { inner_it, inner_i ->
                if (inner_i == 0) {
                    assert inner_it.isNumber() && inner_it.toInteger() % 2
                } else {
                    assert !inner_it.isNumber()
                }
            }.size == 4
        } else {
            assert false: "Please use semantic versioning witch 4 sections, you are using ${$ { i } + 1} section instead"
        }
    }.size == 4
}

android {
    compileSdkVersion project.compileSdkVersion
    buildToolsVersion project.buildToolsVersion
    resourcePrefix "weex"
    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'
//    }

    def ndkversion = 16;
    def api_level = "";
    def compile_tool = "clang";
    def cxx_stl = "c++_static";
    if (ndkversion < 16) {
        api_level = "android-14";
    } else {
        api_level = "android-19";
    }

    defaultConfig {
        buildConfigField "String", "buildJavascriptFrameworkVersion", "\"${jsfmVersion}\""
        buildConfigField "String", "buildVersion", "\"${version}\""
        minSdkVersion project.minSdkVersion
        targetSdkVersion project.targetSdkVersion

        multiDexEnabled true

        versionCode 1
        versionName project.version
        ndk {
            abiFilters "armeabi-v7a", "armeabi", "x86"
        }
        externalNativeBuild {
            cmake {
                arguments '-DANDROID_PLATFORM=' + "${api_level}",
                        '-DANDROID_TOOLCHAIN=' + "${compile_tool}",
                        '-DANDROID_STL=' + "${cxx_stl}",
                        '-DCMAKE_BUILD_TYPE=Release',
                        '-DENABLE_ASAN=false'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            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
            testCoverageEnabled disableCov.toBoolean()
            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')
        excludes(['com/taobao/weex/utils/WXDataStructureUtil.java'])
    }

    task weex_core_license(type: com.hierynomus.gradle.license.tasks.LicenseFormat){
        source = fileTree(dir:"../../weex_core").include(['**/*.h','**/*.cpp', '**/*.cc', '**/*.c']).
                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', 'Source/IPC/**/*.c',
                         'Source/android/jsengine/dependence/**/*.h',
                         'Source/android/jsengine/dependence/**/*.cpp',
                         'Source/include/wtf/**/*.h',
                         'Source/include/wtf/**/*.c',
                         'Source/include/wtf/**/*.cpp',
                         'Source/include/JavaScriptCore/**/*.h',
                         'Source/include/JavaScriptCore/**/*.c',
                         'Source/include/JavaScriptCore/**/*.cpp'])
    }
    preBuild.dependsOn licenseFormat
}

task checkNdkVersion() {
    def rootDir = project.rootDir
    def localProperties = new File(rootDir, "local.properties")
    def ndkDir = ''
    if (localProperties.exists()) {
        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        ndkDir = properties.getProperty('ndk.dir')
    }

    if(null == ndkDir){
        def errMsg ='please set ndk.dir path in project/local.properties and ndk-16 supported only,example: ndk.dir=/Users/xxx/Library/Android/sdk/ndk-bundle-r16'
        throw new StopActionException(errMsg)
    }

    if(!ndkDir.isEmpty()) {
        def sourcePropertiesFile = new File(ndkDir,"source.properties")
        def ndkVersion = ''
        println("sourcePropertiesFile" + sourcePropertiesFile.absolutePath)
        if(sourcePropertiesFile.exists()) {
            Properties properties = new Properties()
            sourcePropertiesFile.withInputStream { instr ->
                properties.load(instr)
            }

            ndkVersion = properties.getProperty('Pkg.Revision')
        }

        if(ndkVersion.length() > 2) {
            def substring = ndkVersion.substring(0, 2)
            try {
                if(substring.toInteger() != 16) {
                    throw new StopActionException("Ndk Version 16 supported only")
                }
            } catch (Exception ignored) {
                println("Ndk Version 16 supported only")
            }

        } else {
            println("Ndk Version 16 supported only")
        }
    } else {
        println("Ndk Version 16 supported only")
    }
}

preBuild.dependsOn checkNdkVersion

def siteUrl = 'https://weex.incubator.apache.org'
def gitUrl = 'https://github.com/apache/incubator-weex.git'
group = "com.taobao.android"
install {
    repositories.mavenInstaller {
        // This generates POM.xml with proper parameters
        pom {
            project {
                packaging 'aar'
                name 'weex_sdk'
                url siteUrl
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'https://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id 'weex alibaba'
                        name 'weex alibaba'
                        email 'alibabaweex@gmail.com'
                    }
                }
                scm {
                    connection gitUrl
                    developerConnection gitUrl
                    url siteUrl
                }
            }
        }
    }
}

task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

artifacts {
    archives sourcesJar
}

bintray {
    configurations = ['archives']
    user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
    key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
    pkg {
        repo = "maven"
        name = "weex_sdk"
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = ["Apache-2.0"]
        publish = true
        version {
            //The version to be published
            name = project.version
            vcsTag = project.version
        }
    }
}

afterEvaluate {
    transformNativeLibsWithStripDebugSymbolForRelease << {
        copy{
            from transformNativeLibsWithMergeJniLibsForRelease
            into new File(project.buildDir, "unstrippedSo")
            include '**/libweexjss.so', '**/libweexcore.so'
            eachFile {
                it.path = "${it.relativePath.segments[5]}_${it.name}"
            }
        }
    }
}