/*
 * Copyright 2022 the original author or authors.
 * <p>
 * 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
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.
 */
package org.openrewrite.maven;

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.Issue;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import java.util.Collections;

import static org.openrewrite.java.Assertions.mavenProject;
import static org.openrewrite.maven.Assertions.pomXml;

class RemoveRedundantDependencyVersionsTest implements RewriteTest {

    @Override
    public void defaults(RecipeSpec spec) {
        spec.recipe(new RemoveRedundantDependencyVersions(null, null, null, null));
    }

    @Test
    void givenScopeIsDefinedWhenVersionMatchesParentDmForDifferentScopeThenStillRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                              <scope>test</scope>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                                <scope>compile</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <scope>compile</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void givenScopeIsDefinedWhenVersionMatchesParentDmForSameScopeAndCompileAndEmptyThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                              <scope>compile</scope>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void givenScopeIsDefinedWhenVersionMatchesParentDmForSameScopeAndEmptyAndCompileThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                                <scope>compile</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <scope>compile</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void givenScopeIsDefinedWhenVersionMatchesParentDmForSameScopeThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                              <scope>test</scope>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                                <scope>test</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <scope>test</scope>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void matchesParentDmThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                <project>
                    <parent>
                        <groupId>org.example</groupId>
                        <artifactId>parent</artifactId>
                        <version>1.0-SNAPSHOT</version>
                    </parent>
                    <artifactId>child</artifactId>
                    <dependencies>
                        <dependency>
                            <groupId>com.google.guava</groupId>
                            <artifactId>guava</artifactId>
                        </dependency>
                    </dependencies>
                </project>
                """
            )
          )
        );
    }

    @DocumentExample
    @Test
    void matchesOwnDmThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
                  <dependencies>
                      <dependency>
                          <groupId>com.google.guava</groupId>
                          <artifactId>guava</artifactId>
                          <version>30.0-jre</version>
                      </dependency>
                  </dependencies>
              </project>
              """,
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
                  <dependencies>
                      <dependency>
                          <groupId>com.google.guava</groupId>
                          <artifactId>guava</artifactId>
                      </dependency>
                  </dependencies>
              </project>
              """
          )
        );
    }

    @Test
    void givenVersionMatchesParentDmWhenOwnDmIsDifferentThenKeepIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencyManagement>
                            <dependencies>
                                <dependency>
                                    <groupId>com.google.guava</groupId>
                                    <artifactId>guava</artifactId>
                                    <version>29.0-jre</version>
                                </dependency>
                            </dependencies>
                        </dependencyManagement>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void whenNoParentOrOwnDmThenKeepIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <modelVersion>4.0.0</modelVersion>
                  <groupId>com.mycompany</groupId>
                  <artifactId>myApiApp</artifactId>
                  <version>1.0.0</version>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <modelVersion>4.0.0</modelVersion>
                        <groupId>com.mycompany</groupId>
                        <artifactId>mySharedLibrary</artifactId>
                        <version>1.0.0</version>
                        <parent>
                            <groupId>com.mycompany</groupId>
                            <artifactId>myApiApp</artifactId>
                            <version>1.0.0</version>
                        </parent>
                        
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void whenNoVersionDefinedThenMakeNoChanges() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>com.mycompany</groupId>
                  <artifactId>myApiApp</artifactId>
                  <version>1.0.0</version>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <modelVersion>4.0.0</modelVersion>
                        <groupId>com.mycompany</groupId>
                        <artifactId>mySharedLibrary</artifactId>
                        <version>1.0.0</version>
                        <parent>
                            <groupId>com.mycompany</groupId>
                            <artifactId>myApiApp</artifactId>
                            <version>1.0.0</version>
                        </parent>
                        
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void doesntMatchParentDmOrOwnDmThenKeepIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>com.mycompany</groupId>
                  <artifactId>myApiApp</artifactId>
                  <version>1.0.0</version>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <groupId>com.mycompany</groupId>
                        <artifactId>mySharedLibrary</artifactId>
                        <version>1.0.0</version>
                        <parent>
                            <groupId>com.mycompany</groupId>
                            <artifactId>myApiApp</artifactId>
                            <version>1.0.0</version>
                        </parent>
                        <dependencyManagement>
                            <dependencies>
                                <dependency>
                                    <groupId>com.google.guava</groupId>
                                    <artifactId>guava</artifactId>
                                    <version>29.0-jre</version>
                                </dependency>
                            </dependencies>
                        </dependencyManagement>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>28.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void givenNestedPomsWhenVersionMatchesImmediateParentThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>29.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <modules>
                            <module>child-2</module>
                        </modules>
                        <dependencyManagement>
                            <dependencies>
                                <dependency>
                                    <groupId>com.google.guava</groupId>
                                    <artifactId>guava</artifactId>
                                    <version>30.0-jre</version>
                                </dependency>
                            </dependencies>
                        </dependencyManagement>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                            </dependency>
                        </dependencies>
                    </project>
                """
            ),
            mavenProject("child-2",
              pomXml(
                """
                      <project>
                          <parent>
                              <groupId>org.example</groupId>
                              <artifactId>child</artifactId>
                              <version>1.0-SNAPSHOT</version>
                          </parent>
                          <artifactId>child-2</artifactId>
                          <dependencies>
                              <dependency>
                                  <groupId>com.google.guava</groupId>
                                  <artifactId>guava</artifactId>
                                  <version>30.0-jre</version>
                              </dependency>
                          </dependencies>
                      </project>
                  """,
                """
                  <project>
                      <parent>
                          <groupId>org.example</groupId>
                          <artifactId>child</artifactId>
                          <version>1.0-SNAPSHOT</version>
                      </parent>
                      <artifactId>child-2</artifactId>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                          </dependency>
                      </dependencies>
                  </project>
                  """
              )
            )
          )
        );
    }

    @Test
    void givenNestedPomsWhenVersionMatchesTopLevelParentThenRemoveIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>29.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <modules>
                            <module>child-2</module>
                        </modules>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                            </dependency>
                        </dependencies>
                    </project>
                """
            ),
            mavenProject("child-2",
              pomXml(
                """
                      <project>
                          <parent>
                              <groupId>org.example</groupId>
                              <artifactId>child</artifactId>
                              <version>1.0-SNAPSHOT</version>
                          </parent>
                          <artifactId>child-2</artifactId>
                          <dependencies>
                              <dependency>
                                  <groupId>com.google.guava</groupId>
                                  <artifactId>guava</artifactId>
                                  <version>29.0-jre</version>
                              </dependency>
                          </dependencies>
                      </project>
                  """,
                """
                  <project>
                      <parent>
                          <groupId>org.example</groupId>
                          <artifactId>child</artifactId>
                          <version>1.0-SNAPSHOT</version>
                      </parent>
                      <artifactId>child-2</artifactId>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                          </dependency>
                      </dependencies>
                  </project>
                  """
              )
            )
          )
        );
    }

    @Test
    void givenNestedPomsWhenVersionMatchesTopLevelParentAndDoesntMatchFirstLevelParentThenKeepIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>29.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <modules>
                            <module>child-module-2</module>
                        </modules>
                        <dependencyManagement>
                            <dependencies>
                                <dependency>
                                    <groupId>com.google.guava</groupId>
                                    <artifactId>guava</artifactId>
                                    <version>30.0-jre</version>
                                </dependency>
                            </dependencies>
                        </dependencyManagement>
                    </project>
                """
            ),
            mavenProject("child-2",
              pomXml(
                """
                      <project>
                          <parent>
                              <groupId>org.example</groupId>
                              <artifactId>child</artifactId>
                              <version>1.0-SNAPSHOT</version>
                          </parent>
                          <artifactId>child-module-2</artifactId>
                          <dependencies>
                              <dependency>
                                  <groupId>com.google.guava</groupId>
                                  <artifactId>guava</artifactId>
                                  <version>29.0-jre</version>
                              </dependency>
                          </dependencies>
                      </project>
                  """
              )
            )
          )
        );
    }

    @Test
    void givenNestedPomsWhenVersionDoesntMatchAnyDmThenKeepIt() {
        rewriteRun(
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>29.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml(
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <modules>
                            <module>child-2</module>
                        </modules>
                        <dependencyManagement>
                            <dependencies>
                                <dependency>
                                    <groupId>com.google.guava</groupId>
                                    <artifactId>guava</artifactId>
                                    <version>28.0-jre</version>
                                </dependency>
                            </dependencies>
                        </dependencyManagement>
                    </project>
                """
            ),
            mavenProject("child-2",
              pomXml(
                """
                      <project>
                          <parent>
                              <groupId>org.example</groupId>
                              <artifactId>child</artifactId>
                              <version>1.0-SNAPSHOT</version>
                          </parent>
                          <artifactId>child-2</artifactId>
                          <dependencies>
                              <dependency>
                                  <groupId>com.google.guava</groupId>
                                  <artifactId>guava</artifactId>
                                  <version>30.0-jre</version>
                              </dependency>
                          </dependencies>
                      </project>
                  """
              )
            )
          )
        );
    }

    @Test
    void onlyIfVersionsMatchFalse() {
        rewriteRun(
          spec -> spec.recipe(new RemoveRedundantDependencyVersions(null, null, false, null)),
          pomXml(
            """
              <project>
                  <groupId>org.example</groupId>
                  <artifactId>parent</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <modules>
                      <module>child</module>
                  </modules>
                  <dependencyManagement>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>31.0-jre</version>
                          </dependency>
                      </dependencies>
                  </dependencyManagement>
              </project>
              """
          ),
          mavenProject("child",
            pomXml("""
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                                <version>30.0-jre</version>
                            </dependency>
                        </dependencies>
                    </project>
                """,
              """
                    <project>
                        <parent>
                            <groupId>org.example</groupId>
                            <artifactId>parent</artifactId>
                            <version>1.0-SNAPSHOT</version>
                        </parent>
                        <artifactId>child</artifactId>
                        <dependencies>
                            <dependency>
                                <groupId>com.google.guava</groupId>
                                <artifactId>guava</artifactId>
                            </dependency>
                        </dependencies>
                    </project>
                """
            )
          )
        );
    }

    @Test
    void except() {
        rewriteRun(
          spec -> spec.recipe(new RemoveRedundantDependencyVersions(null, null, false, Collections.singletonList("org.junit.jupiter:junit-jupiter-api"))),
          pomXml("""
                <project>
                    <parent>
                        <groupId>org.junit</groupId>
                        <artifactId>junit-bom</artifactId>
                        <version>5.8.0</version>
                    </parent>
                    <artifactId>child</artifactId>
                    <dependencies>
                        <dependency>
                            <groupId>org.junit.jupiter</groupId>
                            <artifactId>junit-jupiter-api</artifactId>
                            <version>5.8.0</version>
                        </dependency>
                        <dependency>
                            <groupId>org.junit.jupiter</groupId>
                            <artifactId>junit-jupiter-params</artifactId>
                            <version>5.8.0</version>
                        </dependency>
                    </dependencies>
                </project>
                """,
            """
                <project>
                    <parent>
                        <groupId>org.junit</groupId>
                        <artifactId>junit-bom</artifactId>
                        <version>5.8.0</version>
                    </parent>
                    <artifactId>child</artifactId>
                    <dependencies>
                        <dependency>
                            <groupId>org.junit.jupiter</groupId>
                            <artifactId>junit-jupiter-api</artifactId>
                            <version>5.8.0</version>
                        </dependency>
                        <dependency>
                            <groupId>org.junit.jupiter</groupId>
                            <artifactId>junit-jupiter-params</artifactId>
                        </dependency>
                    </dependencies>
                </project>
                  """
          )
        );
    }

    @Test
    @Issue("https://github.com/openrewrite/rewrite/issues/3268")
    void unmanagedDependency() {
        rewriteRun(
          pomXml(
            """
                  <project>
                      <groupId>org.sample</groupId>
                      <artifactId>sample</artifactId>
                      <version>1.0.0</version>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </project>
              """
          )
        );
    }

    @Test
    @Issue("https://github.com/openrewrite/rewrite/issues/3268")
    void unmanagedDependencyOnlyIfVersionsMatchFalse() {
        rewriteRun(
          spec -> spec.recipe(new RemoveRedundantDependencyVersions(null, null, false, null)),
          pomXml(
            """
                  <project>
                      <groupId>org.sample</groupId>
                      <artifactId>sample</artifactId>
                      <version>1.0.0</version>
                      <dependencies>
                          <dependency>
                              <groupId>com.google.guava</groupId>
                              <artifactId>guava</artifactId>
                              <version>30.0-jre</version>
                          </dependency>
                      </dependencies>
                  </project>
              """
          )
        );
    }
}
