import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

final class StaxLintSupport {
  private StaxLintSupport() { }

  static void run(String name, String[] args, XMLInputFactory factory) {
    if (args.length != 1) {
      System.err.println("usage: " + name + " FILE");
      System.exit(2);
    }

    try {
      factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
      factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
      factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
      factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
      try {
        factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
      } catch (IllegalArgumentException ignored) {
        // Aalto does not expose this JAXP property; resolver + DTD rejection below enforce the policy.
      }
      factory.setXMLResolver((publicId, systemId, baseUri, namespace) -> {
        throw new XMLStreamException("External entities are disabled");
      });

      try (InputStream stream = Files.newInputStream(Path.of(args[0]))) {
        XMLStreamReader reader = factory.createXMLStreamReader(stream);
        try {
          while (reader.hasNext()) {
            if (reader.next() == XMLStreamConstants.DTD) {
              throw new XMLStreamException("DOCTYPE is disabled");
            }
          }
        } finally {
          reader.close();
        }
      }
    } catch (Exception error) {
      System.err.println(error.getClass().getSimpleName() + ": " + error.getMessage());
      System.exit(1);
    }
  }
}
