package de.bmoth.architecture;

import guru.nidi.codeassert.config.AnalyzerConfig;
import guru.nidi.codeassert.dependency.DependencyRule;
import guru.nidi.codeassert.dependency.DependencyRuler;
import guru.nidi.codeassert.dependency.DependencyRules;
import guru.nidi.codeassert.model.ModelAnalyzer;
import org.junit.Before;
import org.junit.Test;

import java.io.File;

import static guru.nidi.codeassert.junit.CodeAssertMatchers.*;
import static org.junit.Assert.assertThat;

public class DependencyTest {
    private String[] packages = new String[]{"app", "backend", "checkers", "eventbus", "modelchecker", "parser"};
    private AnalyzerConfig config;

    @Before
    public void setup() {
        // Analyze all sources in src/main/java
        config = new AnalyzerConfig();
        config = config.withSources(new File("src/main/java/de/bmoth"), packages);
        config = config.withClasses(new File("build/classes/main/de/bmoth"), packages);
    }

    @Test
    public void noCycles() {
        assertThat(new ModelAnalyzer(config).analyze(), hasNoClassCycles());
        assertThat(new ModelAnalyzer(config).analyze(), hasNoPackageCycles());
    }

    @Test
    public void dependency() {
        class ExternalPackages extends DependencyRuler {
            DependencyRule comMicrosoftZ3,
                comMicrosoftZ3Enumerations,
                deBmothApp,
                deBmothBackendZ3,
                deBmothModelchecker,
                deBmothCheckers_,
                deSaxsysMvvmfx;

            @Override
            public void defineRules() {
                deBmothApp.mayUse(comMicrosoftZ3, comMicrosoftZ3Enumerations, deSaxsysMvvmfx);
                deBmothBackendZ3.mustUse(comMicrosoftZ3);
                deBmothBackendZ3.mayUse(comMicrosoftZ3Enumerations);
                deBmothModelchecker.mustUse(comMicrosoftZ3);
                deBmothCheckers_.mustUse(comMicrosoftZ3);
            }
        }

        class DeBmoth extends DependencyRuler {
            // $self is de.bmoth, added _ refers to subpackages of package
            DependencyRule app,
                antlr,
                backend,
                backend_,
                checkers_,
                eventbus,
                modelchecker,
                parser,
                parser_,
                preferences;

            @Override
            public void defineRules() {
                app.mayUse(backend_, checkers_, eventbus, modelchecker, parser, parser_, preferences);

                backend_.mayUse(preferences, backend, parser, parser_);

                checkers_.mayUse(backend, backend_, parser, parser_);

                modelchecker.mayUse(backend, backend_, parser_, preferences);

                parser.mayUse(antlr, parser_);
                parser_.mayUse(antlr, parser_);
            }
        }

        // All dependencies are forbidden, except the ones defined above
        // java, javafx, com and org are ignored
        // maybe we should include com.microsoft again and check who is
        // allowed to directly speak to z3
        DependencyRules rules = DependencyRules.denyAll()
            .withAbsoluteRules(new ExternalPackages())
            .withRelativeRules(new DeBmoth())
            .withExternals("com.google.*", "java.*", "javafx.*", "org.*");

        assertThat(new ModelAnalyzer(config).analyze(), packagesMatchExactly(rules));
    }
}

@@ -544,17 +544,19 @@
 String%5B%5D
-%7B
+ %7B 
 %22app%22, %22
@@ -613,16 +613,17 @@
 %22parser%22
+ 
 %7D;%0A    p
@@ -1298,32 +1298,16 @@
 osoftZ3,
-%0A               
  comMicr
@@ -1330,52 +1330,20 @@
 ons,
-%0A                deBmothApp,%0A               
+ deBmothApp,
  deB
@@ -1357,16 +1357,20 @@
 kendZ3,%0A
+    
         
@@ -1397,32 +1397,16 @@
 checker,
-%0A               
  deBmoth
@@ -1415,32 +1415,16 @@
 eckers_,
-%0A               
  deSaxsy
@@ -1875,23 +1875,32 @@
   class 
-DeBmoth
+InternalPackages
  extends
@@ -1934,102 +1934,170 @@
     
-// $self is de.b
+DependencyRule deB
 moth
-, added _ refers to subpackages of package%0A            DependencyRule app,
+ParserAst, deBmothParserAst_, deBmothParserCst, deBmothParserAstNodes,%0A                    deBmothParserAstTypes, deBmothParserAstVisitors;%0A
 %0A   
@@ -2109,18 +2109,17 @@
     
-    antlr,
+@Override
 %0A   
@@ -2131,99 +2131,257 @@
     
-    backend,%0A                backend_,%0A                checkers_,%0A                eventbus,
+public void defineRules() %7B%0A                deBmothParserAst.mustUse(deBmothParserAst_, deBmothParserCst);%0A                deBmothParserAstNodes.mustUse(deBmothParserAstTypes);%0A                deBmothParserAstVisitors.mustUse(deBmothParserAstNodes);
 %0A   
@@ -2393,65 +2393,244 @@
     
+%7D%0A
     
-modelchecker,%0A                parser,%0A               
+    %7D%0A%0A        class DeBmoth extends DependencyRuler %7B%0A            // $self is de.bmoth, added _ refers to subpackages of package%0A            DependencyRule app, antlr, backend, backend_, checkers_, eventbus, modelchecker, parser,
  par
@@ -2635,16 +2635,20 @@
 arser_,%0A
+    
         
@@ -2666,16 +2666,27 @@
 ferences
+, parserAst
 ;%0A%0A     
@@ -3148,33 +3148,68 @@
 mayUse(antlr
-, parser_
+);%0A%0A                parserAst.mayUse(backend
 );%0A         
@@ -3518,17 +3518,63 @@
 enyAll()
-%0A
+.withAbsoluteRules(new InternalPackages())%0A    
         
@@ -3619,29 +3619,16 @@
 kages())
-%0A            
 .withRel
@@ -3649,24 +3649,28 @@
  DeBmoth())%0A
+    
             

extend dependency test