package com.github.sormuras.bach.internal;

import com.github.sormuras.bach.Project;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.net.URI;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Stream;

public record DeclaredModules(ModuleFinder finder) {
  public static DeclaredModules of(Set<Project.Module> modules) {
    var map = new TreeMap<String, Reference>();
    for (var module : modules) map.put(module.name(), new Reference(module));
    return new DeclaredModules(new Finder(map));
  }

  public Stream<ModuleDescriptor> descriptors() {
    return finder().findAll().stream().sorted().map(ModuleReference::descriptor);
  }

  public Stream<String> names() {
    return descriptors().map(ModuleDescriptor::name);
  }

  private record Finder(Map<String, Reference> map) implements ModuleFinder {

    @Override
    public Optional<ModuleReference> find(String name) {
      return Optional.ofNullable(map.get(name));
    }

    @Override
    public Set<ModuleReference> findAll() {
      return Set.copyOf(map.values());
    }
  }

  private static final class Reference extends ModuleReference implements Comparable<Reference> {

    private Reference(Project.Module module) {
      super(module.descriptor(), module.location());
    }

    @Override
    public int compareTo(Reference other) {
      return descriptor().name().compareTo(other.descriptor().name());
    }

    @Override
    public ModuleReader open() {
      return new EmptyModuleReader();
    }
  }

  private record EmptyModuleReader() implements ModuleReader {

    @Override
    public Optional<URI> find(String name) {
      return Optional.empty();
    }

    @Override
    public Stream<String> list() {
      return Stream.empty();
    }

    @Override
    public void close() {}
  }
}

@@ -395,22 +395,27 @@
 %0Apublic 
-record
+final class
  Declare
@@ -426,32 +426,12 @@
 ules
-(ModuleFinder finder)
  %7B%0A
+%0A
   pu
@@ -500,176 +500,225 @@
     
-var map = new TreeMap%3CString, Reference%3E();%0A    for (var module : modules) map.put(module.name(), new Reference(module));%0A    return new DeclaredModules(new F
+return new DeclaredModules(Finder.of(modules));%0A  %7D%0A%0A  private final Finder finder;%0A%0A  public DeclaredModules(Finder finder) %7B%0A    this.finder = finder;%0A  %7D%0A%0A  public boolean isEmpty() %7B%0A    return f
 inder
-(map)
+.map.isEmpty(
 );%0A 
@@ -792,36 +792,28 @@
 nder
-().findAll().stream().sorted
+.map.values().stream
 ().m
@@ -1018,24 +1018,251 @@
 leFinder %7B%0A%0A
+    private static Finder of(Set%3CProject.Module%3E modules) %7B%0A      var map = new TreeMap%3CString, Reference%3E();%0A      for (var module : modules) map.put(module.name(), new Reference(module));%0A      return new Finder(map);%0A    %7D%0A%0A
     @Overrid
@@ -1550,41 +1550,8 @@
 ence
- implements Comparable%3CReference%3E
  %7B%0A%0A
@@ -1661,144 +1661,8 @@
  %7D%0A%0A
-    @Override%0A    public int compareTo(Reference other) %7B%0A      return descriptor().name().compareTo(other.descriptor().name());%0A    %7D%0A%0A
     

Store `Finder` in internal `DeclaredModules` class