// ***************************************************************************************************************************
// * 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");

			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("{OVERVIEW_URL}","")).replace("{CONTENTS}", contents.toString()).replace("{TOC-RELEASE-NOTES}", tocRn).replace("{RELEASE-NOTES}", rn);

			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);
		}
	}
}
