package de.is24.deadcode4j.analyzer;

import de.is24.deadcode4j.Analyzer;
import de.is24.deadcode4j.CodeContext;
import org.junit.Before;
import org.junit.Test;

import java.util.Map;

import static com.google.common.collect.Iterables.concat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;

public final class A_ReferenceToConstantsAnalyzer extends AnAnalyzer {

    private Analyzer objectUnderTest;
    private CodeContext codeContext;

    @Before
    public void setUp() throws Exception {
        objectUnderTest = new ReferenceToConstantsAnalyzer();
        codeContext = new CodeContext();
    }

    @Test
    public void recognizesDependencyToConstantInMethod() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantInMethod.java"));
    }

    @Test
    public void recognizesDependencyToConstantInField() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantInField.java"));
    }

    @Test
    public void recognizesDependencyToFullyQualifiedConstantInField() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingFQConstantInField.java"));

        assertDependencyExists("de.is24.deadcode4j.analyzer.constants.ClassUsingFQConstantInField", "de.is24.deadcode4j.analyzer.constants.Constants");
    }

    @Test
    public void recognizesDependencyToConstantOfOtherPackageInMethod() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageInMethod.java"));
    }

    @Test
    public void recognizesDependencyToFullyQualifiedConstantOfOtherPackageInMethod() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingFQConstantOfOtherPackageInMethod.java"));

        assertDependencyExists("de.is24.deadcode4j.analyzer.constants.subpackage.ClassUsingFQConstantOfOtherPackageInMethod", "de.is24.deadcode4j.analyzer.constants.Constants");
    }

    @Test
    public void recognizesDependencyToConstantOfOtherPackageReferencedViaStaticImportInMethod() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingStaticImportForConstantOfOtherPackageInMethod.java"));
    }

    @Test
    public void recognizesOverwrittenConstantOfOtherPackageReferencedViaStaticImportInMethod() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameLocalName.java"));
    }

    @Test
    public void recognizesDependencyToFullyQualifiedConstantInExpression() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingFQConstantInExpression.java"));

        assertDependencyExists("de.is24.deadcode4j.analyzer.constants.ClassUsingFQConstantInExpression", "de.is24.deadcode4j.analyzer.constants.Constants");
    }

    @Test
    public void recognizesDependencyToInnerClassInsteadOfPackageClass() {
        objectUnderTest.doAnalysis(codeContext, getFile("../../src/test/java/de/is24/deadcode4j/analyzer/constants/ClassWithInnerClassNamedLikePotentialTarget.java"));
    }

    private void assertDependencyExists(String depender, String dependee) {
        Map<String, ? extends Iterable<String>> codeDependencies = codeContext.getAnalyzedCode().getCodeDependencies();
        assertThat(codeDependencies.keySet(), containsInAnyOrder(depender));

        Iterable<String> allReportedClasses = concat(codeDependencies.values());
        assertThat(allReportedClasses, containsInAnyOrder(dependee));
    }

}

@@ -740,51 +740,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -832,33 +832,32 @@
 tInMethod.java%22)
-)
 ;%0A    %7D%0A%0A    @Te
@@ -929,51 +929,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -1020,33 +1020,32 @@
 ntInField.java%22)
-)
 ;%0A    %7D%0A%0A    @Te
@@ -1131,51 +1131,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -1224,33 +1224,32 @@
 ntInField.java%22)
-)
 ;%0A%0A        asser
@@ -1489,51 +1489,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -1606,33 +1606,32 @@
 eInMethod.java%22)
-)
 ;%0A    %7D%0A%0A    @Te
@@ -1732,51 +1732,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -1855,25 +1855,24 @@
 ethod.java%22)
-)
 ;%0A%0A        a
@@ -2167,51 +2167,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -2303,25 +2303,24 @@
 ethod.java%22)
-)
 ;%0A    %7D%0A%0A   
@@ -2435,51 +2435,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -2555,25 +2555,24 @@
 lName.java%22)
-)
 ;%0A    %7D%0A%0A   
@@ -2667,51 +2667,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -2773,17 +2773,16 @@
 n.java%22)
-)
 ;%0A%0A     
@@ -3036,51 +3036,15 @@
     
-objectUnderTest.doAnalysis(codeContext, get
+analyze
 File
@@ -3153,16 +3153,138 @@
 t.java%22)
+;%0A    %7D%0A%0A    private void analyzeFile(String fileName) %7B%0A        objectUnderTest.doAnalysis(codeContext, getFile(fileName)
 );%0A    %7D

better express intent