/*
 * Copyright 2021, TeamDev. All rights reserved.
 *
 * 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
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.tools.gradle.project;

import io.spine.tools.gradle.GeneratedSourceRoot;
import io.spine.tools.gradle.GeneratedSourceSet;
import org.gradle.api.Project;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Path;

import static com.google.common.truth.Truth.assertThat;
import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME;
import static org.gradle.api.tasks.SourceSet.TEST_SOURCE_SET_NAME;

@DisplayName("ProjectSourceSuperset should")
class ProjectSourceSupersetTest {

    private Project project;

    @BeforeEach
    void setUp(@TempDir Path projectPath) {
        project = ProjectBuilder
                .builder()
                .withProjectDir(projectPath.toFile())
                .build();
        project.getPluginManager()
               .apply(JavaPlugin.class);
    }

    @Test
    @DisplayName("mark a given generated code root as a source set in `main` scope")
    void addSourceSet() {
        checkMarks(MAIN_SOURCE_SET_NAME);
    }

    @Test
    @DisplayName("mark a given generated code root as a source set in `test` scope")
    void addTestSourceSet() {
        checkMarks(TEST_SOURCE_SET_NAME);
    }

    private void checkMarks(String sourceSetName) {
        GeneratedSourceRoot root = GeneratedSourceRoot.of(project);
        ProjectSourceSuperset structure = ProjectSourceSuperset.of(project);
        structure.register(root);

        SourceSet sourceSet = sourceSet(sourceSetName);
        SourceDirectorySet javaDirs = sourceSet.getJava();
        GeneratedSourceSet generatedSourceSet = root.sourceSet(sourceSetName);
        assertThat(javaDirs.getSrcDirs()).containsAtLeast(generatedSourceSet.java().toFile(),
                                                          generatedSourceSet.grpc().toFile(),
                                                          generatedSourceSet.spine().toFile());
        assertThat(sourceSet.getResources().getSrcDirs())
                .contains(generatedSourceSet.resources().toFile());
    }

    private SourceSet sourceSet(String name) {
        JavaPluginConvention javaConvention = project.getConvention()
                                                     .getPlugin(JavaPluginConvention.class);
        SourceSetContainer sourceSets = javaConvention.getSourceSets();
        SourceSet sourceSet = sourceSets.getByName(name);
        assertThat(sourceSet).isNotNull();
        return sourceSet;
    }
}

@@ -1521,123 +1521,23 @@
 api.
-plugins.JavaPluginConvention;%0Aimport org.gradle.api.tasks.SourceSet;%0Aimport org.gradle.api.tasks.SourceSetContainer
+tasks.SourceSet
 ;%0Aim
@@ -1825,16 +1825,81 @@
 rtThat;%0A
+import static io.spine.tools.gradle.ProjectExtensions.sourceSet;%0A
 import s
@@ -2039,16 +2039,17 @@
 ayName(%22
+%60
 ProjectS
@@ -2061,16 +2061,17 @@
 Superset
+%60
  should%22
@@ -3028,32 +3028,41 @@
 Set = sourceSet(
+project, 
 sourceSetName);%0A
@@ -3537,24 +3537,24 @@
 tSrcDirs())%0A
+
             
@@ -3618,423 +3618,7 @@
    %7D
-%0A%0A    private SourceSet sourceSet(String name) %7B%0A        JavaPluginConvention javaConvention = project.getConvention()%0A                                                     .getPlugin(JavaPluginConvention.class);%0A        SourceSetContainer sourceSets = javaConvention.getSourceSets();%0A        SourceSet sourceSet = sourceSets.getByName(name);%0A        assertThat(sourceSet).isNotNull();%0A        return sourceSet;%0A    %7D
 %0A%7D%0A

Address deprecations