/*
 * 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 {
        jcenter()
    }

    dependencies {
        classpath ("io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE")
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.1.RELEASE")
    }
}

plugins {
    id 'com.github.hierynomus.license' version '0.13.1'
    id("org.nosphere.apache.rat") version "0.3.1"
}

group 'org.apache.fineract.cn'
version '0.1.0-BUILD-SNAPSHOT'

ext.versions = [
        frameworkservicestarter : '0.1.0-BUILD-SNAPSHOT',
        fineractcnidentity      : '0.1.0-BUILD-SNAPSHOT',
        fineractcnprovisioner   : '0.1.0-BUILD-SNAPSHOT',
        fineractcnrhythm        : '0.1.0-BUILD-SNAPSHOT',
        fineractcnoffice        : '0.1.0-BUILD-SNAPSHOT',
        fineractcncustomer      : '0.1.0-BUILD-SNAPSHOT',
        fineractcnaccounting    : '0.1.0-BUILD-SNAPSHOT',
        fineractcnportfolio     : '0.1.0-BUILD-SNAPSHOT',
        fineractcndeposit       : '0.1.0-BUILD-SNAPSHOT',
        fineractcnteller        : '0.1.0-BUILD-SNAPSHOT',
        fineractcnreporting     : '0.1.0-BUILD-SNAPSHOT',
        kuelapcheques           : '0.1.0-BUILD-SNAPSHOT',
        fineractcnpayroll       : '0.1.0-BUILD-SNAPSHOT',
        fineractcngroup         : '0.1.0-BUILD-SNAPSHOT',
        fineractcnnotification  : '0.1.0-BUILD-SNAPSHOT',
        frameworkapi            : '0.1.0-BUILD-SNAPSHOT',
        frameworklang           : '0.1.0-BUILD-SNAPSHOT',
        frameworktest           : '0.1.0-BUILD-SNAPSHOT',
        frameworkanubis         : '0.1.0-BUILD-SNAPSHOT',
        defaultsetup            : '0.1.0-BUILD-SNAPSHOT',
        validator               : '5.3.0.Final'
]

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'spring-boot'
apply plugin: 'maven-publish'

tasks.withType(JavaCompile) {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

repositories {
    jcenter()
    mavenLocal()
}

dependencyManagement {
    imports {
        mavenBom 'io.spring.platform:platform-bom:Athens-RELEASE'
        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Camden.SR1'
    }
}

// override certain dependency provided by Spring platform using newer releases
ext['cassandra.version'] = '3.6'
ext['cassandra-driver.version'] = '3.1.2'
ext['activemq.version'] = '5.13.2'
ext['spring-data-releasetrain.version'] = 'Gosling-SR2A'

dependencies {
    compile(
            [group: 'com.google.code.findbugs', name: 'jsr305'],
            [group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka-server'],
            [group: 'org.apache.fineract.cn.office', name: 'api', version: versions.fineractcnoffice],
            [group: 'org.apache.fineract.cn.provisioner', name: 'api', version: versions.fineractcnprovisioner],
            [group: 'org.apache.fineract.cn.identity', name: 'api', version: versions.fineractcnidentity],
            [group: 'org.apache.fineract.cn.rhythm', name: 'api', version: versions.fineractcnrhythm],
            [group: 'org.apache.fineract.cn.rhythm', name: 'spi', version: versions.fineractcnrhythm],

            [group: 'org.apache.fineract.cn.customer', name: 'api', version: versions.fineractcncustomer],
            [group: 'org.apache.fineract.cn.accounting', name: 'api', version: versions.fineractcnaccounting],
            [group: 'org.apache.fineract.cn.accounting', name: 'importer', version: versions.fineractcnaccounting],
            [group: 'org.apache.fineract.cn.portfolio', name: 'api', version: versions.fineractcnportfolio],
            [group: 'org.apache.fineract.cn.deposit-account-management', name: 'api', version: versions.fineractcndeposit],
            [group: 'org.apache.fineract.cn.teller', name: 'api', version: versions.fineractcnteller],
            [group: 'org.apache.fineract.cn.reporting', name: 'api', version: versions.fineractcnreporting],
            [group: 'org.apache.fineract.cn.cheques', name: 'api', version: versions.kuelapcheques],
            [group: 'org.apache.fineract.cn.payroll', name: 'api', version: versions.fineractcnpayroll],
            [group: 'org.apache.fineract.cn.group', name: 'api', version: versions.fineractcngroup],
            [group: 'org.apache.fineract.cn.notification', name: 'api', version: versions.fineractcnnotification],

            [group: 'org.apache.fineract.cn.anubis', name: 'api', version: versions.frameworkanubis],
            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
            [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
            [group: 'org.apache.fineract.cn', name: 'lang', version: versions.frameworklang],
            [group: 'org.apache.fineract.cn', name: 'service-starter', version: versions.frameworkservicestarter],
            [group: 'org.apache.fineract.cn.default-setup', name: 'accounting', version: versions.defaultsetup],
            [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
            [group: 'org.eclipse.aether', name: 'aether-api', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-spi', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-util', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-impl', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-connector-basic', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-transport-file', version: '1.1.0'],
            [group: 'org.eclipse.aether', name: 'aether-transport-http', version: '1.1.0'],
            [group: 'org.apache.maven', name: 'maven-aether-provider', version: '3.1.0'],
            [group: 'org.springframework.boot', name: 'spring-boot-starter-test']
    )
}

publishToMavenLocal.dependsOn bootRepackage

license {
    header rootProject.file('HEADER')
    strictCheck true
    mapping {
        java = 'SLASHSTAR_STYLE'
        xml = 'XML_STYLE'
        yml = 'SCRIPT_STYLE'
        yaml = 'SCRIPT_STYLE'
    }
}

rat {
    // List of exclude directives, defaults to ['**/.gradle/**']
    excludes = [
            "**/.idea/**",
            "**/.gradle/**",
            "**/gradle/**",
            "**/build/**",
            "logs/**",
            "target/**",
            "gradlew",
            "gradlew.bat",
            "README.md"
    ]
}