/*
 *  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.
 */
allprojects {
    apply plugin: 'eclipse'

    eclipse.classpath.file.whenMerged {
        entries.removeAll { entry -> entry.path =~ '/target/' } // affects: cli-commons, cli-picocli, console, groovydoc, macro, servlet, swing, templates, xml
        entries.unique(true) { entry -> entry.path } // affects: console, groovydoc, macro, servlet, swing, templates, xml
        entries.sort(true) { entry ->
            if (entry.class.simpleName != 'SourceFolder') {
                "${entry.kind}:${entry.path.split('/')[-1].toLowerCase()}"
            } else {
                "${entry.kind}:${entry.path}"
            }
        }

        // set "test" attribute based on gradle scopes
        entries.findAll { entry ->
            entry.class.name in [
                'org.gradle.plugins.ide.eclipse.model.Library',
                'org.gradle.plugins.ide.eclipse.model.SourceFolder'
            ]
        }.each { entry ->
            if (entry.entryAttributes['gradle_used_by_scope'] == 'test') {
                entry.entryAttributes['test'] = 'true'
            }
        }
        // set "test" attribute based on configuration
        entries.findAll { entry ->
            entry.class.name in [
                'org.gradle.plugins.ide.eclipse.model.ProjectDependency'
            ]
        }.each { entry ->
            if (entry.path.substring(1) in project.configurations.testImplementation.dependencies*.name) {
                entry.entryAttributes['test'] = 'true'
            }
        }
    }

    project.tasks.eclipse.doLast {
        file("${project.projectDir}/.settings/org.eclipse.jdt.groovy.core.prefs").with { prefs ->
            if (!prefs.exists()) {
                append('''\
                    eclipse.preferences.version=1
                    groovy.compiler.level=30
                    groovy.script.filters=**/*.gradle,n,**/script*.groovy,y,**/*resources/**/*.groovy,y,**/benchmarks/**/*.groovy,y
                    org.codehaus.groovy.eclipse.preferences.compiler.project=true
                    '''.stripIndent()
                )
            }
        }

        file("${project.projectDir}/.settings/org.eclipse.core.resources.prefs").with { prefs ->
            if (!prefs.exists()) {
                append('''\
                    eclipse.preferences.version=1
                    encoding/<project>=UTF-8
                    '''.stripIndent()
                )
            }
        }

        file("${project.projectDir}/.settings/org.eclipse.core.runtime.prefs").with { prefs ->
            if (!prefs.exists()) {
                append('''\
                    eclipse.preferences.version=1
                    line.separator=\\n
                    '''.stripIndent()
                )
            }
        }

        file("${project.projectDir}/.settings/org.eclipse.jdt.ui.prefs").with { prefs ->
            if (!prefs.exists()) {
                append('''\
                    eclipse.preferences.version=1
                    editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
                    org.eclipse.jdt.ui.ignorelowercasenames=true
                    org.eclipse.jdt.ui.importorder=;javax;java;\\#;
                    org.eclipse.jdt.ui.ondemandthreshold=99
                    org.eclipse.jdt.ui.staticondemandthreshold=99
                    sp_cleanup.on_save_use_additional_actions=true
                    sp_cleanup.organize_imports=true
                    sp_cleanup.remove_trailing_whitespaces=true
                    sp_cleanup.remove_trailing_whitespaces_all=true
                    sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
                    sp_cleanup.update_copyright_notice=true
                    '''.stripIndent()
                )
            }
        }
    }

    // tasks for cleaning the .settings files created above

    task cleanEclipseGdt(type: Delete) {
        delete "${project.projectDir}/.settings/org.eclipse.jdt.groovy.core.prefs"
    }
    cleanEclipse.dependsOn(cleanEclipseGdt)

    task cleanEclipseJdtUI(type: Delete) {
        delete "${project.projectDir}/.settings/org.eclipse.jdt.ui.prefs"
    }
    cleanEclipse.dependsOn(cleanEclipseJdtUI)

    project.tasks.cleanEclipse.doLast {
        file("${project.projectDir}/.settings/org.eclipse.core.resources.prefs").delete()
        file("${project.projectDir}/.settings/org.eclipse.core.runtime.prefs").delete()
        file("${project.projectDir}/.settings/").with { if (!listFiles()) delete() }
    }
}

eclipse.classpath.file.whenMerged {
    entries.removeAll { entry -> entry.path == '/groovy-groovydoc' }

    entries.findAll { entry -> entry.path =~ '^target/generated/sources/antlr' }.each { entry ->
        entry.entryAttributes['ignore_optional_problems'] = 'true'
        entry.entryAttributes['optional'] = 'true'
    }
}
