/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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.
 */

def supportRootFolder = ext.supportRootFolder
if (supportRootFolder == null) {
    throw new RuntimeException("Canonical root project directory is not set. You must specify " +
            "ext.supportRootFolder before including this script")
}
// Makes strong assumptions about the project structure.
def checkoutRoot = supportRootFolder.parentFile.parentFile

ext.repos = new Properties()
ext.repos.checkoutRoot = checkoutRoot.absolutePath
ext.repos.prebuiltsRoot = new File(checkoutRoot, "prebuilts").absolutePath

/**
 * Adds maven repositories to the given repository handler.
 */
def addMavenRepositories(RepositoryHandler handler) {
    handler.maven {
        url "${repos.prebuiltsRoot}/androidx/internal"
        metadataSources {
            mavenPom()
            artifact()
        }
        content {
            includeGroupByRegex "android.*"
            includeGroupByRegex "com.android.support.*"
            excludeGroupByRegex "androidx.databinding.*"
        }
    }
    handler.ivy {
        // TODO: maybe we can move this no-group ivy repo directly into prebuilts/androidx/external
        // once https://youtrack.jetbrains.com/issue/KT-35049 gets resolved */
        url "${repos.prebuiltsRoot}/androidx/external/no-group"
        patternLayout {
            artifact("[artifact]/[revision]/[artifact]-[revision].[ext]")
        }
        metadataSources {
            it.artifact()
        }
        content {
            includeGroup ""
        }
    }
    def buildDokka = System.getenv("BUILD_DOKKA") != null
    handler.maven {
        url "${repos.prebuiltsRoot}/androidx/external"
        metadataSources {
            mavenPom()
            artifact()
        }
        if (buildDokka) {
            content {
                excludeGroup "org.jetbrains.dokka"
            }
        }
    }
    if (buildDokka) {
        handler.maven {
            url "${repos.checkoutRoot}/external/dokka/build/dist-maven"
            content {
                includeGroup "org.jetbrains.dokka"
            }
        }
    }
    if (System.getenv("ALLOW_PUBLIC_REPOS") != null) {
        handler.mavenCentral()
        handler.jcenter()
        handler.google()
        handler.maven {
            url "https://plugins.gradle.org/m2/"
        }
        handler.mavenLocal()
    }
    def androidPluginRepoOverride = System.getenv("GRADLE_PLUGIN_REPO")
    if (androidPluginRepoOverride != null) {
        for(extraRepo in androidPluginRepoOverride.split(File.pathSeparator)) {
            handler.maven {
                url extraRepo
            }
        }
    }
}

ext.repos.addMavenRepositories = this.&addMavenRepositories
