/*
 * 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/base/third_party/icu/*.h',
                         'Source/base/third_party/icu/*.cpp',
                         '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}"
            }
        }
    }
}