/*
 * 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',
        fineractcncheques       : '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.fineractcncheques],
            [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"
    ]
}