//package fr.emse.gitlab.saref.jobs;
//
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.nio.charset.StandardCharsets;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.util.ArrayList;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Set;
//
//import org.apache.commons.io.FileUtils;
//import org.apache.commons.io.IOUtils;
//import org.apache.jena.atlas.io.IndentedWriter;
//import org.apache.jena.graph.NodeFactory;
//import org.apache.jena.query.Dataset;
//import org.apache.jena.query.ReadWrite;
//import org.apache.jena.rdf.model.Model;
//import org.apache.jena.sparql.core.Var;
//import org.apache.jena.sparql.engine.binding.Binding;
//import org.apache.jena.sparql.engine.binding.BindingHashMap;
//import org.apache.jena.sparql.util.Context;
//import org.semanticweb.owlapi.model.OWLOntologyIRIMapper;
//
//import fr.emse.ci.sparqlext.SPARQLExt;
//import fr.emse.ci.sparqlext.engine.PlanFactory;
//import fr.emse.ci.sparqlext.engine.RootPlan;
//import fr.emse.ci.sparqlext.stream.LocationMapperAccept;
//import fr.emse.ci.sparqlext.stream.LocatorFileAccept;
//import fr.emse.ci.sparqlext.stream.LookUpRequest;
//import fr.emse.ci.sparqlext.stream.SPARQLExtStreamManager;
//import fr.emse.ci.sparqlext.utils.ContextUtils;
//import fr.emse.ci.sparqlext.utils.VarUtils;
//import fr.emse.gitlab.saref.Constants;
//import fr.emse.gitlab.saref.entities.tests.TestSuite;
//import fr.emse.gitlab.saref.entities.tests.TestSuites;
//import fr.emse.gitlab.saref.vocabs.EX;
//
//public class CreateDocumentation extends JobRunner {
//	private final SPARQLExtStreamManager streamManager;
//
//	public CreateDocumentation(String testSuiteName, SPARQLExtStreamManager streamManager) {
//		super(testSuiteName);
//		this.streamManager = streamManager;
//	}
//	
//	public void doJob(Dataset dataset, File directory) {
//		dataset.begin(ReadWrite.READ);
//		for (Iterator<String> it = dataset.listNames(); it.hasNext();) {
//			String name = it.next();
//			if (name.equals(EX.config)) {
//				continue;
//			}
//			Model model = dataset.getNamedModel(name);
//			try (IndentedWriter writer = new IndentedWriter(new FileOutputStream(new File(SITE_DIR, fileName + ".html")));) {
//				Context context = ContextUtils.build(writer).setBase(Constants.BASE).setDebugTemplate(Constants.PRODUCTION).setInputDataset(dataset)
//						.setStreamManager(sm)
//						.build();
//				BindingHashMap binding = new BindingHashMap();
//				binding.add(VAR_GRAPH, NodeFactory.createURI(name));
//				List<Binding> bindings = new ArrayList()<>();
//				bindings.add(binding);
//				planForTerm.execTemplateStream(bindings, context);
//			}
//		}
//		dataset.end();
//	}
//	
//	
//		
//		
////	static final Logger LOG = LoggerFactory.getLogger(Documentation.class);
////	
////	static final Gson gson = new Gson();
////
////	static final Pattern REGEX_REPO_PATTERN = Pattern.compile("^saref(-core|4[a-z][a-z][a-z][a-z])$", Pattern.CASE_INSENSITIVE);
////
////	static final File GIT_DIR = new File("target/sources");
////	static final File SITE_DIR = new File("target/site");
////	static final File STATIC_TARGET_DIR = new File("target/site/static");
////	static final String DATASET_DIR = "target/tdb";
////
////	static final String NS = "https://saref.etsi.org/";
////	private static final String REGEX_EXT = "(?<ext>core|saref4[a-z][a-z][a-z][a-z])";
////	private static final String REGEX_VERSION = "v(?<major>[1-9][0-9]*)\\.(?<minor>[0-9]+)\\.(?<patch>[0-9]+)";
////	
////	private static final String REGEX_RELEASE_BRANCH = "^refs/remotes/origin/release-" + REGEX_VERSION + "$";
////	private static final Pattern REGEX_RELEASE_BRANCH_PATTERN = Pattern.compile(REGEX_RELEASE_BRANCH);
////
////	private static final String REGEX_TERM_URI = "^" + NS + REGEX_EXT + "/(?<localName>[^/]+)$";
////	private static final Pattern REGEX_TERM_PATTERN = Pattern.compile(REGEX_TERM_URI);
////	
////	private static final String REGEX_ONTO_URI = "^" + NS + REGEX_EXT + "/" + REGEX_VERSION + "/$";
////	private static final Pattern REGEX_ONTO_PATTERN = Pattern.compile(REGEX_ONTO_URI);
////
////	private static final String REGEX_EXT_URI = "^" + NS + REGEX_EXT + "/";
////	private static final Pattern REGEX_EXT_PATTERN = Pattern.compile(REGEX_EXT_URI);
////
////	private static Dataset dataset;
////	private static final Model config = ModelFactory.createDefaultModel();
////	private static final Map<String, Model> ngs = new HashMap<>();
////
////	private static final Resource ETSI_URL = ResourceFactory.createResource("https://www.etsi.org/");
////	private static final Resource ETSI_LICENSE = ResourceFactory
////			.createResource("https://forge.etsi.org/etsi-software-license");
////
////	private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
////
////	static final String DOC_NS = NS + "documentation/";
////	private static final String TERM_QUERY = "term/main.rqg";
////	private static final Var VAR_GRAPH = VarUtils.allocVar("term");
////
////	static final String urlString = "https://forge.etsi.org/rep/api/v4/groups/saref";
////
////	static final boolean useTDB = true;
////
////	
////	
////	public static void main(String[] args) throws MalformedURLException, IOException {
////		// do we have a directory named ontology here ? if not, we assume that we are executing from a repo.
////		File ontologyDir = new File("ontology");
////		
////		
////		
////		dataset = TDBFactory.createDataset(DATASET_DIR);
//////		Model m = dataset.getNamedModel("https://saref.etsi.org/core/accomplishes");
//////		m.write(System.out, "TTL");
////		try {
////			checkFolderStructure();
////
////			checkUnusedTerms();
////
////			checkNameConflicts();
////
////			Group group = readGroup();
////			
////			cloneRepos(group);
////			
//////			Group group = new Group();
//////			List<Project> projects = new ArrayList<>();
//////			group.projects = projects;
//////
//////			Project repo = new Project();
//////			repo.name = "saref-core";
//////			repo.directory = new File(GIT_DIR, repo.name);
//////			repo.namespace = getNamespace(repo);
//////			repo.prefix = getPrefix(repo);
//////			projects.add(repo);
//////
//////			repo = new Project();
//////			repo.name = "saref4ener";
//////			repo.directory = new File(GIT_DIR, repo.name);
//////			repo.namespace = getNamespace(repo);
//////			repo.prefix = getPrefix(repo);
//////			projects.add(repo);
////
////			readRepos(group);
////
////			writeToTDBDataset();
////
//
////
////			SPARQLExtStreamManager sm = initializeStreamManager();
////
////			RootPlan planForTerm = createPlanForTerm(sm);
////
////			generateFiles(sm, planForTerm);
////		} finally {
////			dataset.close();
////		}
////
////	}
////
////
////	
////	private static void checkFolderStructure() {
////
////	}
////
////	private static void checkUnusedTerms() {
////		/*
////		 * Query to find terms that are not defined in any ontology:
////		 * 
////		 * PREFIX ex: <http://example.org/> PREFIX rdfs:
////		 * <http://www.w3.org/2000/01/rdf-schema#> SELECT ?term ?version WHERE {
////		 * 
////		 * ?term ex:isUsedBy ?version . MINUS { ?term rdfs:isDefinedBy ?v2 . } }
////		 * 
////		 */
////	}
////
////	private static void checkNameConflicts() {
////		/*
////		 * Query to find local name conflicts in different ontologies
////		 * 
////		 * PREFIX ex: <http://example.org/> PREFIX rdfs:
////		 * <http://www.w3.org/2000/01/rdf-schema#> SELECT DISTINCT * WHERE {
////		 * 
////		 * ?term1 ex:localName ?name ; rdfs:isDefinedBy ?v1 . ?term2 ex:localName ?name
////		 * ; rdfs:isDefinedBy ?v2 . FILTER( ?term1 != ?term2 ) }
////		 * 
////		 */
////	}
////
////
////	private static Group readGroup() throws IOException {
////		final URL url = new URL(urlString);
////		InputStreamReader reader = new InputStreamReader(url.openStream());
////		return gson.fromJson(reader, Group.class);
////	}
////
////	private static void writeToTDBDataset() {
////		dataset.begin(ReadWrite.WRITE);
////		dataset.addNamedModel(EX.config, config);
////		for (String name : ngs.keySet()) {
////			dataset.addNamedModel(name, ngs.get(name));
////		}
////		
////		Model defaultModel = dataset.getDefaultModel();
////		defaultModel.add(ResourceFactory.createResource("s"), ResourceFactory.createProperty("p"), ResourceFactory.createResource("o"));
////		dataset.commit();
////	}
////
////	private static void readRepos(Group group) throws IOException {
////		for (Project repo : group.projects) {
////			try (Git git = Git.open(repo.directory);) {
////				readRepo(repo, git);
////			}
////		}
////	}
////
////	static String getNamespace(String  graphName) {
////		Matcher m = REGEX_EXT_PATTERN.matcher(graphName);
////		if (!m.find()) {
////			throw new IllegalArgumentException("got " + graphName);
////		}
////		return NS + m.group("ext") + "/";
////	}
////
////	static String getOntologyFileName(Project project) {
////		if (project.name.equals("saref-core")) {
////			return "saref.ttl";
////		} else {
////			return String.format("%s.ttl", project.name);
////		}
////	}
////
////	static String getNamespace(Project project) {
////		if (project.name.equals("saref-core")) {
////			return String.format("%score/", NS);
////		} else {
////			return String.format("%s%s/", NS, project.name);
////		}
////	}
////
////	static String getPrefix(String graphName) {
////		Matcher m = REGEX_EXT_PATTERN.matcher(graphName);
////		if (!m.find()) {
////			throw new IllegalArgumentException("got " + graphName);
////		}
////		String ext = m.group("ext");
////		if(ext.equals("core")) {
////			return "saref:";
////		} else {
////			String shortName = ext.substring(5);
////			return String.format("s%s:", shortName);
////		}
////	}
////
////	static String getPrefix(Project project) {
////		if (project.name.equals("saref-core")) {
////			return "saref:";
////		} else {
////			String shortName = project.name.substring(5);
////			return String.format("s%s:", shortName);
////		}
////	}
////
////	static String getVersionURI(Project project, Version version) {
////		if (project.name.equals("saref-core")) {
////			return String.format("%s%sv%s.%s.%s/", NS, "core/", version.major, version.minor, version.patch);
////		} else {
////			return String.format("%s%s/v%s.%s.%s/", NS, project.name, version.major, version.minor, version.patch);
////		}
////	}
////
////	static String getVersionPrefix(Project project, Version version) {
////		if (project.name.equals("saref-core")) {
////			return String.format("saref-%s.%s.%s:", version.major, version.minor, version.patch);
////		} else {
////			String shortName = project.name.substring(5);
////			return String.format("s%s-%s.%s.%s:", shortName, version.major, version.minor, version.patch);
////		}
////	}
////
////	private static void cloneRepos(Group group) throws IOException {
////		FileUtils.forceMkdir(GIT_DIR);
////		for (Project repo : new ArrayList<>(group.projects)) {
////			if (!REGEX_REPO_PATTERN.matcher(repo.name).matches()) {
////				group.projects.remove(repo);
////				continue;
////			}
////			repo.directory = new File(GIT_DIR, repo.name);
////			repo.namespace = getNamespace(repo);
////			repo.prefix = getPrefix(repo);
////			if (repo.directory.exists()) {
////				continue;
////			}
////			LOG.debug("Cloning project " + repo.name);
////			try (Git git = Git.cloneRepository().setURI(repo.http_url_to_repo).setDirectory(repo.directory).call()) {
////			} catch (Exception ex) {
////				LOG.warn("Could not clone project " + repo.name, ex);
////			}
////		}
////	}
////
////	private static void readRepo(Project repo, Git git) {
////		System.out.println("project" + repo.name);
////
////		repo.resource = ResourceFactory.createResource(repo.namespace);
////		config.add(repo.resource, RDF.type, OWL2.Ontology);
////
////		try {
////			List<Ref> remoteBranches = git.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call();
////			for (Ref ref : remoteBranches) {
////				String branch = ref.getName();
////				Matcher m = REGEX_RELEASE_BRANCH_PATTERN.matcher(branch);
////				if (!m.find()) {
////					continue;
////				}
////				Version version = new Version();
////				version.major = Integer.parseInt(m.group("major"));
////				version.minor = Integer.parseInt(m.group("minor"));
////				version.patch = Integer.parseInt(m.group("patch"));
////				version.uri = getVersionURI(repo, version);
////				version.resource = ResourceFactory.createResource(version.uri);
////				version.prefix = getVersionPrefix(repo, version);
////				version.ref = ref;
////				RevCommit commit = git.log().add(version.ref.getObjectId()).call().iterator().next();
////				version.issued = commit.getCommitterIdent().getWhen();
////				repo.releases.add(version);
////				System.out.println("version " + version);
////			}
////
////			// order versions
////			Collections.sort(repo.releases, (Version o1, Version o2) -> {
////				if (o1.major - o2.major != 0) {
////					return o1.major - o2.major;
////				}
////				if (o1.minor - o2.minor != 0) {
////					return o1.minor - o2.minor;
////				}
////				return o1.patch - o2.patch;
////			});
////
////			for (int i = 0; i < repo.releases.size(); i++) {
////				Version version = repo.releases.get(i);
////
////				Model onto = readOntology(repo, version);
////				ngs.put(version.uri, onto);
////
////				// compute some metadata
////				Version priorVersion = i == 0 ? null : repo.releases.get(i - 1);
////				addOntologyMetadata(onto, repo, git, version, priorVersion);
////
////				// for each term, add:
////				// some triples in the default graph
////				// -> used to detect naming clashes
////				// some triples in the named graph of the term
////				// -> used to display the page of the term
////				Set<Resource> definedTerms = new HashSet<>();
////				Set<Resource> usedTerms = new HashSet<>();
////				computeTerms(onto, repo, version, definedTerms, usedTerms);
////				config.add(repo.resource, EX.hasVersion, version.resource);
////				config.add(version.resource, RDF.type, EX.OntologyVersion);
////				config.add(version.resource, EX.versionInfo,
////						String.format("v%s.%s.%s", version.major, version.minor, version.patch));
////				if (priorVersion != null) {
////					config.add(version.resource, EX.priorVersion, priorVersion.resource);
////				}
////
////				for (Resource t : definedTerms) {
////					Model termModel = getNamedModel(t);
////					String localName = t.getURI().substring(repo.namespace.length());
////					termModel.add(t, RDFS.isDefinedBy, version.resource);
////					// keep the most recent definition of the term
////					if (i == repo.releases.size() - 1) {
////						termModel.add(t, DCTerms.modified, SIMPLE_DATE_FORMAT.format(version.issued),
////								XSDDatatype.XSDdate);
////						try (QueryExecution exec = QueryExecutionFactory.create("DESCRIBE <" + t.getURI() + ">",
////								onto)) {
////							termModel.add(exec.execDescribe());
////						}
////					}
////					config.add(t, RDF.type, RDFP.Resource);
////					config.add(t, EX.localName, localName);
////					config.add(t, RDFS.isDefinedBy, version.resource);
////				}
////
////				for (Resource t : usedTerms) {
////					Model termModel = getNamedModel(t);
////					termModel.add(t, EX.isUsedBy, version.resource);
////					config.add(t, RDF.type, RDFP.Resource);
////					config.add(t, EX.isUsedBy, version.resource);
////				}
////			}
////		} catch (Exception ex) {
////			LOG.warn("Exception for " + repo.name, ex);
////		}
////	}
////
////	private static Model readOntology(Project repo, Version version) throws Exception {
////		// checkout the HEAD of the release branch
////		Git.open(repo.directory).checkout().setName(version.ref.getName()).call();
////		Model onto = ModelFactory.createDefaultModel();
////		// read the ontology
////		File ontologyFile = new File(repo.directory, "ontology/" + getOntologyFileName(repo));
////		try (FileReader fr = new FileReader(ontologyFile)) {
////			onto.read(fr, NS, "TTL");
////		}
////		return onto;
////	}
////
////	private static void addOntologyMetadata(Model onto, Project repo, Git git, Version version, Version priorVersion)
////			throws Exception {
////		onto.add(repo.resource, RDF.type, OWL2.Ontology);
////
////		// we assume dc:title, dc:description, rdfs:comment, are defined, and have
////		// language tags
////		onto.removeAll(repo.resource, OWL2.versionIRI, null);
////		onto.add(repo.resource, OWL2.versionIRI, version.resource);
////
////		onto.removeAll(repo.resource, OWL2.versionInfo, null);
////		onto.add(repo.resource, OWL2.versionInfo,
////				String.format("v%s.%s.%s", version.major, version.minor, version.patch));
////
////		onto.removeAll(repo.resource, OWL2.priorVersion, null);
////		if (priorVersion != null) {
////			onto.add(repo.resource, OWL2.priorVersion, priorVersion.resource);
////		}
////
////		onto.removeAll(repo.resource, DCTerms.publisher, null);
////		onto.add(repo.resource, DCTerms.publisher, ETSI_URL);
////
////		onto.removeAll(repo.resource, DCTerms.license, null);
////		onto.add(repo.resource, DCTerms.license, ETSI_LICENSE);
////
////		// list of contributors
////		Set<Contributor> contributors = new HashSet<>();
////		for (Iterator<RevCommit> it = git.log().add(version.ref.getObjectId()).call().iterator(); it.hasNext();) {
////			RevCommit commit = it.next();
////			Contributor contributor = new Contributor(commit.getCommitterIdent());
////			contributors.add(contributor);
////		}
////		for (Contributor contributor : contributors) {
////			// git can only provide name + email.
////			// would need to maintain some list of mapping email -> url in the future.
////			Resource anon = onto.createResource();
////			onto.add(repo.resource, DCTerms.contributor, anon);
////			onto.add(anon, FOAF.name, contributor.getName());
////			onto.add(anon, FOAF.mbox, contributor.getEmailAddress());
////		}
////
////		// prefixes
////		onto.removeAll(repo.resource, VANN.preferredNamespacePrefix, null);
////		onto.removeAll(repo.resource, VANN.preferredNamespaceUri, null);
////		onto.add(repo.resource, VANN.preferredNamespacePrefix, repo.prefix);
////		onto.add(repo.resource, VANN.preferredNamespaceUri, repo.namespace, XSDDatatype.XSDanyURI);
////
////		// issued
////		onto.removeAll(repo.resource, DCTerms.issued, null);
////		onto.add(repo.resource, DCTerms.issued, SIMPLE_DATE_FORMAT.format(version.issued), XSDDatatype.XSDdate);
////	}
////
////	private static void computeTerms(Model onto, Project repo, Version version, Set<Resource> definedTerms,
////			Set<Resource> usedTerms) {
////		onto.listStatements().forEachRemaining(stmt -> {
////			Resource s = stmt.getSubject();
////			Resource p = stmt.getPredicate();
////			Resource o = stmt.getObject().isResource() ? (Resource) stmt.getObject() : null;
////			computeTerms(s, repo, version, definedTerms, usedTerms);
////			computeTerms(p, repo, version, definedTerms, usedTerms);
////			computeTerms(o, repo, version, definedTerms, usedTerms);
////		});
////	}
////
////	private static void computeTerms(Resource t, Project repo, Version version, Set<Resource> definedTerms,
////			Set<Resource> usedTerms) {
////		if (t == null || !t.isURIResource() || !t.getURI().startsWith(NS) || t.getURI().endsWith("/")) {
////			return;
////		}
////		String uri = t.getURI();
////		if (uri.startsWith(repo.namespace)) {
////			definedTerms.add(t);
////		} else if (!uri.startsWith(repo.namespace)) {
////			usedTerms.add(t);
////		}
////	}
////
////	private static Model getNamedModel(Resource t) {
////		String uri = t.getURI();
////		if (ngs.containsKey(uri)) {
////			return ngs.get(uri);
////		} else {
////			Model model = ModelFactory.createDefaultModel();
////			model.add(t, RDF.type, RDFS.Resource);
////			ngs.put(uri, model);
////			return model;
////		}
////	}
////
////	private static class EX {
////
////		private static String NS = "http://example.org/";
////		private static String config = NS + "config";
////		private static Property localName = ResourceFactory.createProperty(NS, "localName");
////		private static Property hasVersion = ResourceFactory.createProperty(NS, "hasVersion");
////		private static Property versionInfo = ResourceFactory.createProperty(NS, "versionInfo");
////		private static Property priorVersion = ResourceFactory.createProperty(NS, "priorVersion");
////		private static Property isUsedBy = ResourceFactory.createProperty(NS, "isUsedBy");
////		private static Resource OntologyVersion = ResourceFactory.createResource(NS + "OntologyVersion");
////	}
////
////	private static class VANN {
////
////		private static String NS = "http://purl.org/vocab/vann/";
////		private static Property preferredNamespacePrefix = ResourceFactory.createProperty(NS,
////				"preferredNamespacePrefix");
////		private static Property preferredNamespaceUri = ResourceFactory.createProperty(NS, "preferredNamespaceUri");
////	}
////
////	private static class RDFP {
////		public static final String NS = "https://w3id.org/rdfp/";
////		public static final Property presentedBy = ResourceFactory.createProperty(NS + "presentedBy");
////		public static final Property presentationFor = ResourceFactory.createProperty(NS + "presentationForq");
////		public static final Property loweringRule = ResourceFactory.createProperty(NS + "loweringRule");
////		public static final Property liftingRule = ResourceFactory.createProperty(NS + "liftingRule");
////		public static final Property validationRule = ResourceFactory.createProperty(NS + "validationRule");
////		public static final Resource Graph = ResourceFactory.createResource(NS + "Graph");
////		public static final Resource Resource = ResourceFactory.createResource(NS + "Resource");
////		public static final Property representedBy = ResourceFactory.createProperty(NS + "representedBy");
////		public static final Property mediaType = ResourceFactory.createProperty(NS + "mediaType");
////		public static final Property alias = ResourceFactory.createProperty(NS + "alias");
////		public static final Property describedBy = ResourceFactory.createProperty(NS + "describedBy");
////		public static final Property filePath = ResourceFactory.createProperty(NS + "filePath");
////		public static final Resource Ontology = ResourceFactory.createResource(NS + "Ontology");
////		public static final Property fileSelector = ResourceFactory.createProperty(NS + "fileSelector");
////	}
//
//}
