// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.doc.internal;

import static org.apache.juneau.doc.internal.Console.*;

import java.io.*;
import java.nio.file.*;
import java.util.*;

/**
 * Utility for generating the overview.html page.
 */
public class DocGenerator {

	static List<String> WARNINGS = new ArrayList<>();

	static final String COPYRIGHT = ""
		+ "\n/***************************************************************************************************************************"
		+ "\n * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file"
		+ "\n * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file"
		+ "\n * to you under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance"
		+ "\n * with the License.  You may obtain a copy of the License at"
		+ "\n *  "
		+ "\n *  http://www.apache.org/licenses/LICENSE-2.0"
		+ "\n *  "
		+ "\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an"
		+ "\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the"
		+ "\n * specific language governing permissions and limitations under the License."
		+ "\n ***************************************************************************************************************************/"
	;

	/**
	 * Entry point.
	 *
	 * @param args Not used
	 */
	public static void main(String[] args) {
		if (args.length == 0 || args.length == 1 && args[0].equals("build"))
			build();
		printWarnings();
	}


	private static void build() {
		try {
			long startTime = System.currentTimeMillis();

			String template = IOUtils.readFile("docs/overview_template.html");

			String configProps = ConfigPropsGenerator.run();

			DocStore ds = new DocStore(new File("docs/docs.txt"));

			File top = new File("docs/Topics");

			reorder(top);

			Topics topics = new Topics(top);

			ReleaseNotes releaseNotes = new ReleaseNotes(new File("docs/ReleaseNotes"));

			StringBuilder toc = new StringBuilder("<ol class='toc'>\n"), contents = new StringBuilder();

			for (PageFile pf1 : topics.pageFiles) {
				toc
					.append("\t<li><p class='").append(pf1.tags.isEmpty() ? "toc2" : pf1.tags).append("'><a class='doclink' href='{OVERVIEW_URL}#").append(pf1.fullId).append("'>").append(pf1.title).append("</a></p>\n");
				ds
					.addLink(pf1.fullId, "#" + pf1.fullId, "Overview > " + pf1.title);
				contents
					.append("\n")
					.append("<!-- ==================================================================================================== -->\n\n")
					.append("<h2 class='topic ").append(pf1.tags).append("' onclick='toggle(this)'><a href='#").append(pf1.fullId).append("' id='").append(pf1.fullId).append("'>").append(pf1.fullNumber).append(" - ").append(pf1.title).append("</a></h2>\n")
					.append("<div class='topic'>").append("<!-- START: ").append(pf1.fullNumber).append(" - " ).append(pf1.fullId).append(" -->\n")
					.append(pf1.contents).append("\n");

				if (! pf1.pageFiles.isEmpty()) {

					toc.append("\t<ol>\n");

					for (PageFile pf2 : pf1.pageFiles) {

						toc
							.append("\t\t<li><p class='").append(pf2.tags).append("'><a class='doclink' href='{OVERVIEW_URL}#").append(pf2.fullId).append("'>").append(pf2.title).append("</a></p>\n");
						ds
							.addLink(pf2.fullId, "#" + pf2.fullId, "Overview > " + pf1.title + " > " + pf2.title);
						contents
							.append("\n")
							.append("<!-- ==================================================================================================== -->\n\n")
							.append("<h3 class='topic ").append(pf2.tags).append("' onclick='toggle(this)'><a href='#").append(pf2.fullId).append("' id='").append(pf2.fullId).append("'>").append(pf2.fullNumber).append(" - ").append(pf2.title).append("</a></h3>\n")
							.append("<div class='topic'>").append("<!-- START: ").append(pf2.fullNumber).append(" - " ).append(pf2.fullId).append(" -->\n")
							.append(pf2.contents).append("\n");

						if (! pf2.pageFiles.isEmpty()) {
							toc.append("\t\t<ol>\n");

							for (PageFile pf3 : pf2.pageFiles) {

								toc
									.append("\t\t\t<li><p class='").append(pf3.tags).append("'><a class='doclink' href='{OVERVIEW_URL}#").append(pf3.fullId).append("'>").append(pf3.title).append("</a></p>\n");
								ds
									.addLink(pf3.fullId, "#" + pf3.fullId, "Overview > " + pf1.title + " > " + pf2.title + " > " + pf3.title);
								contents
									.append("\n")
									.append("<!-- ==================================================================================================== -->\n\n")
									.append("<h4 class='topic ").append(pf3.tags).append("' onclick='toggle(this)'><a href='#").append(pf3.fullId).append("' id='").append(pf3.fullId).append("'>").append(pf3.fullNumber).append(" - ").append(pf3.title).append("</a></h4>\n")
									.append("<div class='topic'>").append("<!-- START: ").append(pf3.fullNumber).append(" - " ).append(pf3.fullId).append(" -->\n")
									.append(pf3.contents).append("\n")
									.append("</div>").append("<!-- END: ").append(pf3.fullNumber).append(" - ").append(pf3.fullId).append(" -->\n");
							}

							toc.append("\t\t</ol>\n");
						}

						contents
							.append("</div>").append("<!-- END: ").append(pf2.fullNumber).append(" - ").append(pf2.fullId).append(" -->\n");
					}

					toc.append("\t</ol>\n");
				}

				contents
					.append("</div>").append("<!-- END: ").append(pf1.fullNumber).append(" - ").append(pf1.fullId).append(" -->\n");
			}

			StringBuilder tocRn = new StringBuilder("<ul class='toc'>\n"), rn = new StringBuilder();

			for (ReleaseFile rf : releaseNotes.releaseFiles) {
				tocRn
					.append("<li><p><a class='doclink' href='{OVERVIEW_URL}#").append(rf.version).append("'>").append(rf.title).append("</a></p>\n");
				rn
					.append("\n")
					.append("<!-- ==================================================================================================== -->\n\n")
					.append("<h3 class='topic' onclick='toggle(this)'><a href='#").append(rf.version).append("' id='").append(rf.version).append("'>").append(rf.title).append("</a></h3>\n")
					.append("<div class='topic'>").append("<!-- START: ").append(rf.version).append(" -->\n")
					.append(rf.contents).append("\n")
					.append("</div>").append("<!-- END: ").append(rf.version).append(" -->\n");
			}

			toc.append("</ol>\n");
			tocRn.append("</ul>\n");

			template = template
				.replace("{TOC-CONTENTS}", toc.toString())
				.replace("{CONTENTS}", contents.toString())
				.replace("{TOC-RELEASE-NOTES}", tocRn)
				.replace("{RELEASE-NOTES}", rn)
				.replace("{CONFIG-PROPS}", configProps)
				.replace("{OVERVIEW_URL}", "");

			IOUtils.writeFile("src/main/javadoc/overview.html", template);

			ds.save(new File("src/main/javadoc/resources/docs.txt"));

			info("Generated target/overview.html in {0}ms", System.currentTimeMillis()-startTime);

			startTime = System.currentTimeMillis();
			for (File f : new File("src/main/javadoc/doc-files").listFiles())
				Files.delete(f.toPath());
			for (File f : new File("src/main/javadoc/resources/fragments").listFiles())
				Files.delete(f.toPath());

			for (File f : topics.docFiles)
				Files.copy(f.toPath(), Paths.get("src/main/javadoc/doc-files", f.getName()), StandardCopyOption.REPLACE_EXISTING);
			for (File f : releaseNotes.docFiles)
				Files.copy(f.toPath(), Paths.get("src/main/javadoc/doc-files", f.getName()), StandardCopyOption.REPLACE_EXISTING);

			String toc2 = new StringBuilder().append("<!--").append(COPYRIGHT).append("\n-->\n").append(toc).toString();
			IOUtils.writeFile("src/main/javadoc/resources/fragments/toc.html", toc2);

			String tocRn2 = new StringBuilder().append("<!--").append(COPYRIGHT).append("\n-->\n").append(tocRn).toString();
			IOUtils.writeFile("src/main/javadoc/resources/fragments/rntoc.html", tocRn2);

			info("Copied doc-files in {0}ms", System.currentTimeMillis()-startTime);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void reorder(File dir) throws IOException {
		Topics t = new Topics(dir);

		int i = 1;
		for (PageFile f : t.pageFiles) {
			f.reorder(i++);
		}

		t = new Topics(dir);
		for (PageFile f : t.pageFiles)
			if (f.dir != null)
				reorder(f.dir);
	}

	static class Topics {
		Set<PageFile> pageFiles = new TreeSet<>();
		List<File> docFiles = new ArrayList<>();

		public Topics(File topicsDir) throws IOException {
			for (File f : topicsDir.listFiles()) {
				if (! f.getName().startsWith(".")) {
					if (f.isFile())
						pageFiles.add(new PageFile(null, f, docFiles));
					else if (f.isDirectory() && f.getName().contains("doc-files"))
						docFiles.addAll(Arrays.asList(f.listFiles()));
				}
			}
		}
	}

	static class ReleaseNotes {
		Set<ReleaseFile> releaseFiles = new TreeSet<>();
		List<File> docFiles = new ArrayList<>();

		public ReleaseNotes(File releaseNotesDir) throws IOException {
			for (File f : releaseNotesDir.listFiles()) {
				if (f.isFile())
					releaseFiles.add(new ReleaseFile(f));
				else if (f.isDirectory() && f.getName().contains("doc-files"))
					docFiles.addAll(Arrays.asList(f.listFiles()));
			}
		}
	}

	static class PageFile implements Comparable<PageFile> {
		String idWithNum, id, num, fullId, title, contents;
		String fullNumber;
		int pageNumber, dirNumber;
		String tags = "";
		File file, dir;

		Set<PageFile> pageFiles = new TreeSet<>();

		PageFile(PageFile parent, File f, List<File> docFiles) throws IOException {
			this.file = f;
			try {
				String n = f.getName();
				idWithNum = n.substring(0, n.lastIndexOf('.'));
				num = n.substring(0, n.indexOf('.'));
				id = idWithNum.substring(n.indexOf('.') + 1);
				fullId = (parent == null ? "" : parent.fullId + ".") + id;
				pageNumber = Integer.parseInt(n.substring(0, n.indexOf('.')));
				fullNumber = (parent == null ? "" : parent.fullNumber + ".") + pageNumber;
				String s = IOUtils.read(f);
				int i = s.indexOf("-->");
				s = s.substring(i+4).trim();
				i = s.indexOf("\n");
				title = s.substring(0, i);
				if (title.startsWith("{")) {
					tags = title.substring(1, title.indexOf('}'));
					title = title.substring(tags.length()+2).trim();
				}
				if (s.contains("{@link org.apache.juneau."))
					WARNINGS.add("Found {@link org.apache.juneau...} in file " + f.getAbsolutePath());
				contents = s.substring(i).trim()
					.replaceAll("oaj\\.", "org.apache.juneau.")
					.replaceAll("oajr\\.", "org.apache.juneau.rest.")
					.replaceAll("oajrc\\.", "org.apache.juneau.rest.client.")
				;
			} catch (Exception e) {
				WARNINGS.add("Problem with file " + f.getAbsolutePath() +", " + e.getMessage());
				return;
			}

			for (File d : f.getParentFile().listFiles()) {
				if (d.isDirectory()) {
					String n = d.getName();
					if (n.matches("\\d+\\..*")) {
						int dirNumber = Integer.parseInt(n.substring(0, n.indexOf('.')));
						String dirName = n.substring(n.indexOf('.') + 1);
						if (dirName.equals(id)) {
							this.dirNumber = dirNumber;
							dir = d;
							for (File f2 : d.listFiles()) {
								if (f2.isFile())
									pageFiles.add(new PageFile(this, f2, docFiles));
								else if (f2.isDirectory() && f2.getName().contains("doc-files"))
									docFiles.addAll(Arrays.asList(f2.listFiles()));
							}
						}
					}
				}
			}
		}

		public String getPageDirName(File f) {
			String n = f.getName();
			n = n.substring(n.indexOf('.') + 1);
			return n;
		}

		void reorder(int i) {
			if (pageNumber != i) {
				File f2 = new File(file.getParentFile(), String.format("%0"+num.length()+"d", i) + '.' + id + ".html");
				info("Renaming {0} to {1}", file.getName(), f2.getName());
				file.renameTo(f2);
			}
			if (dir != null && dirNumber != i) {
				File f2 = new File(file.getParentFile(), String.format("%0"+num.length()+"d", i) + '.' + id);
				info("Renaming {0} to {1}", dir.getName(), f2.getName());
				dir.renameTo(f2);
			}
		}

		@Override
		public int compareTo(PageFile o) {
			return this.idWithNum.compareTo(o.idWithNum);
		}
	}

	static void printWarnings() {
		if (WARNINGS.isEmpty())
			info("No DocGenerator warnings.");
		else {
			warning(WARNINGS.size()+" DocGenerator warnings:");
			for (int i = 0; i < WARNINGS.size(); i++)
				warning("["+(i+1)+"] " + WARNINGS.get(i));
		}
	}

	static class ReleaseFile implements Comparable<ReleaseFile> {
		String name, version, title, contents;

		ReleaseFile(File f) throws IOException {
			name = f.getName();
			name = name.substring(0, name.lastIndexOf('.'));
			version = name.replaceAll("[0](\\d+)", "$1");
			String s = IOUtils.read(f);
			int i = s.indexOf("-->");
			s = s.substring(i+4).trim();
			i = s.indexOf("\n");
			title = s.substring(0, i);
			contents = s.substring(i).trim()
				.replaceAll("oaj\\.", "org.apache.juneau.")
				.replaceAll("oajr\\.", "org.apache.juneau.rest.")
				.replaceAll("oajrc\\.", "org.apache.juneau.rest.client.")
			;
		}

		@Override
		public int compareTo(ReleaseFile o) {
			return this.name.compareTo(o.name);
		}
	}
}
