package com.google.doctool;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class DocTool {

  public static final class GenType {
    private GenType() {
    }
  }

  private class ImageCopier extends DefaultHandler {

    private ImageCopier(File htmlDir) {
      fHtmlDir = htmlDir;
    }

    public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
      if (qName.equalsIgnoreCase("img")) {
        String imgSrc = attributes.getValue("src");
        if (imgSrc != null) {
          boolean found = false;
          for (int i = 0, n = fImagePath.length; i < n; ++i) {
            File dir = fImagePath[i];
            File inFile = new File(dir, imgSrc);
            if (inFile.exists()) {
              // Copy it over.
              //
              found = true;
              File outFile = new File(fHtmlDir, imgSrc);

              if (outFile.exists()) {
                if (outFile.lastModified() > inFile.lastModified()) {
                  // Already up to date.
                  break;
                }
              } else {
                File outFileDir = outFile.getParentFile();
                if (!outFileDir.exists() && !outFileDir.mkdirs()) {
                  fErr.println("Unable to create image output dir "
                    + outFileDir);
                  break;
                }
              }
              if (!copyFile(inFile, outFile)) {
                fErr.println("Unable to copy image file " + outFile);
              }
            }
          }
          if (!found) {
            fErr.println("Unable to find image " + imgSrc);
          }
        }
      }
    }

    private final File fHtmlDir;
  }

  private static final Pattern IN_XML_FILENAME = Pattern.compile(
    "(.+)\\.([^\\.]+)\\.xml", Pattern.CASE_INSENSITIVE);

  public static void main(String[] args) {
    DocToolFactory factory = new DocToolFactory();
    String arg;
    String pathSep = System.getProperty("path.separator");
    for (int i = 0, n = args.length; i < n; ++i) {
      if (tryParseFlag(args, i, "-help")) {
        printHelp();
        return;
      } else if (null != (arg = tryParseArg(args, i, "-out"))) {
        ++i;
        factory.setOutDir(arg);
      } else if (null != (arg = tryParseArg(args, i, "-html"))) {
        ++i;
        factory.setGenerateHtml(true);
        factory.setTitle(arg);

        // Slurp every arg not prefixed with "-".
        for (; i + 1 < n && !args[i + 1].startsWith("-"); ++i) {
          factory.addHtmlFileBase(args[i + 1]);
        }
      } else if (null != (arg = tryParseArg(args, i, "-overview"))) {
        ++i;
        factory.setOverviewFile(arg);
      } else if (null != (arg = tryParseArg(args, i, "-sourcepath"))) {
        ++i;
        String[] entries = arg.split("\\" + pathSep);
        for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) {
          factory.addToSourcePath(entries[entryIndex]);
        }
      } else if (null != (arg = tryParseArg(args, i, "-classpath"))) {
        ++i;
        String[] entries = arg.split("\\" + pathSep);
        for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) {
          factory.addToClassPath(entries[entryIndex]);
        }
      } else if (null != (arg = tryParseArg(args, i, "-packages"))) {
        ++i;
        String[] entries = arg.split("\\" + pathSep);
        for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) {
          factory.addToPackages(entries[entryIndex]);
        }
      } else if (null != (arg = tryParseArg(args, i, "-imagepath"))) {
        ++i;
        String[] entries = arg.split("\\" + pathSep);
        for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) {
          factory.addToImagePath(entries[entryIndex]);
        }
      } else {
        if (factory.getFileType() == null)
          factory.setFileType(args[i]);
        else
          factory.setFileBase(args[i]);
      }
    }

    DocTool docTool = factory.create(System.out, System.err);
    if (docTool != null)
      docTool.process();
  }

  public static boolean recursiveDelete(File file) {
    if (file.isDirectory()) {
      File[] children = file.listFiles();
      if (children != null) {
        for (int i = 0; i < children.length; i++) {
          if (!recursiveDelete(children[i]))
            return false;
        }
      }
    }
    if (!file.delete()) {
      System.err.println("Unable to delete " + file.getAbsolutePath());
      return false;
    }
    return true;
  }

  private static void printHelp() {
    String s = "";
    s += "DocTool (filetype filebase)? [docset-creation-options] [html-creation-options]\n";
    s += "    Creates structured javadoc xml output from Java source and/or\n";
    s += "    a table of contents and a set of cross-linked html files.\n";
    s += "    Specifying filebase/filetype produces output file \"filebase.filetype.xml\".\n";
    s += "    Specifying -html produces output files in ${out}/html.\n";
    s += "\n";
    s += "[docset-creation-options] are\n";
    s += "  -out\n";
    s += "    The output directory\n";
    s += "  -overview\n";
    s += "    The overview html file for this doc set\n";
    s += "  -sourcepath path\n";
    s += "    The path to find Java source for this doc set\n";
    s += "  -classpath path\n";
    s += "    The path to find imported classes for this doc set\n";
    s += "  -packages package-names\n";
    s += "    The command-separated list of package names to include in this doc set\n";
    s += "\n";
    s += "[html-creation-options] are\n";
    s += "  -html title filebase+\n";
    s += "    Causes topics in the named filebase(s) to be merged and converted into html\n";
    s += "  -imagepath\n";
    s += "    The semicolon-separated path to find images for html\n";
    System.out.println(s);
  }

  /**
   * Parse a flag with a argument.
   */
  private static String tryParseArg(String[] args, int i, String name) {
    if (i < args.length) {
      if (args[i].equals(name)) {
        if (i + 1 < args.length) {
          String arg = args[i + 1];
          if (arg.startsWith("-")) {
            System.out.println("Warning: arg to " + name
              + " looks more like a flag: " + arg);
          }
          return arg;
        } else {
          throw new IllegalArgumentException("Expecting an argument after "
            + name);
        }
      }
    }
    return null;
  }

  /**
   * Parse just a flag with no subsequent argument.
   */
  private static boolean tryParseFlag(String[] args, int i, String name) {
    if (i < args.length) {
      if (args[i].equals(name))
        return true;
    }
    return false;
  }

  DocTool(PrintStream out, PrintStream err, File outDir, boolean generateHtml,
      String title, String[] htmlFileBases, String fileType, String fileBase,
      File overviewFile, File[] sourcePath, File[] classPath,
      String[] packages, File[] imagePath) {
    fOut = out;
    fErr = err;
    fOutDir = outDir;
    fGenerateHtml = generateHtml;
    fFileBase = fileBase;
    fFileType = fileType;
    fOverviewFile = overviewFile;
    fSourcePath = sourcePath;
    fClassPath = classPath;
    fPackages = packages;
    fImagePath = imagePath;
    fTitle = title;
    fHtmlFileBases = (String[]) htmlFileBases.clone();
  }

  public boolean copyFile(File in, File out) {
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
      fis = new FileInputStream(in);
      fos = new FileOutputStream(out);
      byte[] buf = new byte[4096];
      int i = 0;
      while ((i = fis.read(buf)) != -1) {
        fos.write(buf, 0, i);
      }
      return true;
    } catch (Exception e) {
      return false;
    } finally {
      close(fis);
      close(fos);
    }
  }

  private void close(InputStream is) {
    if (is != null) {
      try {
        is.close();
      } catch (IOException e) {
        e.printStackTrace(fErr);
      }
    }
  }

  private void close(OutputStream os) {
    if (os != null) {
      try {
        os.close();
      } catch (IOException e) {
        e.printStackTrace(fErr);
      }
    }
  }

  private boolean copyImages(File htmlDir, File mergedTopicsFile) {
    FileReader fileReader = null;
    Throwable caught = null;
    try {
      fileReader = new FileReader(mergedTopicsFile);
      SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
      InputSource inputSource = new InputSource(fileReader);
      XMLReader xmlReader = parser.getXMLReader();
      xmlReader.setContentHandler(new ImageCopier(htmlDir));
      xmlReader.parse(inputSource);
      return true;
    } catch (SAXException e) {
      caught = e;
      Exception inner = e.getException();
      if (inner != null)
        caught = inner;
    } catch (ParserConfigurationException e) {
      caught = e;
    } catch (IOException e) {
      caught = e;
    } finally {
      try {
        if (fileReader != null)
          fileReader.close();
      } catch (IOException e) {
        e.printStackTrace(fErr);
      }
    }
    caught.printStackTrace(fErr);
    return false;
  }

  private Set findSourcePackages() {
    Set results = new HashSet();
    for (int i = 0, n = fSourcePath.length; i < n; ++i) {
      File srcDir = fSourcePath[i];
      findSourcePackages(results, srcDir, "");
    }
    return results;
  }

  private void findSourcePackages(Set results, File dir, String parentPackage) {
    File[] children = dir.listFiles();
    if (children != null) {
      for (int i = 0, n = children.length; i < n; ++i) {
        File child = children[i];
        String childName = parentPackage
          + (parentPackage.length() > 0 ? "." : "") + child.getName();
        if (child.isDirectory()) {
          // Recurse
          findSourcePackages(results, child, childName);
        } else if (child.getName().endsWith(".java")) {
          // Only include this dir as a result if there's at least one java file
          results.add(parentPackage);
        }
      }
    }
  }

  private String flattenPath(File[] entries) {
    String pathSep = System.getProperty("path.separator");
    String path = "";
    for (int i = 0, n = entries.length; i < n; ++i) {
      File entry = entries[i];
      if (i > 0)
        path += pathSep;
      path += entry.getAbsolutePath();
    }
    return path;
  }

  private void freshenIf(File file) {
    if (!file.isFile())
      return;

    String name = file.getName();
    Matcher matcher = IN_XML_FILENAME.matcher(name);
    if (matcher.matches()) {
      String suffix = "." + matcher.group(2) + ".xml";
      File topicFile = tryReplaceSuffix(file, suffix, ".topics.xml");
      if (topicFile != null) {
        if (file.lastModified() > topicFile.lastModified()) {
          String xsltFileName = matcher.group(2) + "-" + "topics.xslt";
          String xslt = getFileFromClassPath(xsltFileName); // yucky slow
          fOut.println(file + " -> " + topicFile);
          transform(xslt, file, topicFile, null);
        }
      }
    }
  }

  private boolean genHtml() {
    // Make sure the html directory exists.
    //
    File htmlDir = new File(fOutDir, "html");
    if (!htmlDir.exists() && !htmlDir.mkdirs()) {
      fErr.println("Cannot create html output directory "
        + htmlDir.getAbsolutePath());
      return false;
    }

    // Merge all *.topics.xml into one topics.xml file.
    //
    File mergedTopicsFile = new File(fOutDir, "topics.xml");
    if (!mergeTopics(mergedTopicsFile))
      return false;

    // Parse it all to find the images and copy them over.
    //
    copyImages(htmlDir, mergedTopicsFile);

    // Transform to merged topics into merged htmls.
    //
    File mergedHtmlsFile = new File(htmlDir, "topics.htmls");
    long lastModifiedHtmls = mergedHtmlsFile.lastModified();
    long lastModifiedTopics = mergedTopicsFile.lastModified();
    if (!mergedHtmlsFile.exists() || lastModifiedHtmls < lastModifiedTopics) {
      String xsltHtmls = getFileFromClassPath("topics-htmls.xslt");

      Map params = new HashMap();
      params.put("title", fTitle);

      transform(xsltHtmls, mergedTopicsFile, mergedHtmlsFile, params);

      // Split the merged htmls into many html files.
      //
      if (!splitHtmls(mergedHtmlsFile))
        return false;

      // Create a table of contents.
      //
      File tocFile = new File(htmlDir, "contents.html");
      String xsltToc = getFileFromClassPath("topics-toc.xslt");
      transform(xsltToc, mergedTopicsFile, tocFile, params);

      // Copy the CSS file over.
      //
      String css = getFileFromClassPath("doc.css");
      try {
        FileWriter cssWriter = new FileWriter(new File(htmlDir, "doc.css"));
        cssWriter.write(css);
        cssWriter.close();
      } catch (IOException e) {
        e.printStackTrace(fErr);
      }
    } else {
      fOut
        .println("Skipping html creation since nothing seems to have changed since "
          + mergedHtmlsFile.getAbsolutePath());
    }

    return true;
  }

  private String getFileFromClassPath(String filename) {
    InputStream in = null;
    try {
      in = getClass().getClassLoader().getResourceAsStream(filename);
      try {
        if (in == null) {
          fErr.println("Cannot find file: " + filename);
          System.exit(-1); // yuck
        }
        StringWriter sw = new StringWriter();
        int ch;
        while ((ch = in.read()) != -1) {
          sw.write(ch);
        }
        return sw.toString();
      } finally {
        if (in != null)
          in.close();
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private boolean mergeTopics(File mergedTopicsFile) {
    try {
      List args = new ArrayList();
      args.add("join"); // what to do
      args.add("topics"); // the outer element is <topics>
      args.add(mergedTopicsFile.getAbsolutePath());

      // For each of the htmlFileBases, try to find a file having that name to
      // merge into the big topics doc.
      //
      boolean foundAny = false;
      for (int i = 0, n = fHtmlFileBases.length; i < n; ++i) {
        String filebase = fHtmlFileBases[i];
        File fileToMerge = new File(fOutDir, filebase + ".topics.xml");
        if (fileToMerge.exists()) {
          foundAny = true;
          args.add(fileToMerge.getAbsolutePath());
        } else {
          fErr.println("Unable to find " + fileToMerge.getName());
        }
      }

      if (foundAny) {
        String[] argArray = (String[]) args.toArray(new String[0]);
        traceCommand("SplitterJoiner", argArray);
        SplitterJoiner.main(argArray);
      } else {
        fErr.println("No topics found");
        return false;
      }
    } catch (IOException e) {
      e.printStackTrace(fErr);
      return false;
    }
    return true;
  }

  /**
   * Runs the help process.
   */
  private boolean process() {
    if (fFileType != null) {
      // Produce XML from JavaDoc.
      //
      String fileName = fFileBase + "." + fFileType + ".xml";
      if (!runBooklet(new File(fOutDir, fileName)))
        return false;

    }

    // Process existing files to get them into topics format.
    // Done afterwards for convenience when debugging your doc.
    //
    transformExistingIntoTopicXml();

    if (fGenerateHtml) {
      // Merge into HTML.
      if (!genHtml())
        return false;
    }

    return true;
  }

  private boolean runBooklet(File bkoutFile) {
    // Write out the list of packages that can be found on the source path.
    fOut.println("Creating " + bkoutFile.getAbsolutePath());
    Set srcPackages = findSourcePackages();
    if (srcPackages.isEmpty()) {
      fErr.println("No input files found");
      return false;
    }

    List args = new ArrayList();

    // For now, harded-coded, but could be passed through
    args.add("-source");
    args.add("1.4");

    // The doclet
    args.add("-doclet");
    args.add(Booklet.class.getName());

    // Class path
    args.add("-classpath");
    args.add(flattenPath(fClassPath));

    // Source path
    args.add("-sourcepath");
    args.add(flattenPath(fSourcePath));

    // Overview file
    if (fOverviewFile != null) {
      args.add("-overview");
      args.add(fOverviewFile.getAbsolutePath());
    }

    // Output file
    args.add("-bkout");
    args.add(bkoutFile.getAbsolutePath());

    if (fPackages != null) {
      // Specify the packages to actually emit doc for
      StringBuffer bkdocpkg = new StringBuffer();
      for (int i = 0; i < fPackages.length; i++) {
        String pkg = fPackages[i];
        bkdocpkg.append(pkg);
        bkdocpkg.append(";");
      }
      args.add("-bkdocpkg");
      args.add(bkdocpkg.toString());
    }

    args.add("-breakiterator");
    
    // Specify the set of input packages (needed by JavaDoc)
    args.addAll(srcPackages);

    String[] argArray = (String[]) args.toArray(new String[0]);
    traceCommand("Booklet", argArray);
    Booklet.main(argArray);

    return bkoutFile.exists();
  }

  private boolean splitHtmls(File mergedHtmlsFile) {
    try {
      List args = new ArrayList();
      args.add("split"); // what to do
      args.add(mergedHtmlsFile.getAbsolutePath());
      String[] argArray = (String[]) args.toArray(new String[0]);
      traceCommand("SplitterJoiner", argArray);
      SplitterJoiner.main(argArray);
    } catch (IOException e) {
      e.printStackTrace(fErr);
      return false;
    }
    return true;
  }

  private void traceCommand(String cmd, String[] args) {
    fOut.print(cmd);
    for (int i = 0, n = args.length; i < n; ++i) {
      String arg = args[i];
      fOut.print(" ");
      fOut.print(arg);
    }
    fOut.println();
  }

  private void transform(String xslt, File inFile, File outFile, Map params) {
    Throwable caught = null;
    try {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      StreamSource xsltSource = new StreamSource(new StringReader(xslt));
      Transformer transformer = transformerFactory.newTransformer(xsltSource);
      transformer.setOutputProperty(
        javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
      transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT,
        "yes");
      transformer.setOutputProperty(
        "{http://xml.apache.org/xslt}indent-amount", "4");

      if (params != null) {
        for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
          Map.Entry entry = (Map.Entry) iter.next();
          transformer.setParameter((String) entry.getKey(), entry.getValue());
        }
      }

      FileOutputStream fos = new FileOutputStream(outFile);
      StreamResult result = new StreamResult(fos);
      StreamSource xmlSource = new StreamSource(new FileReader(inFile));
      transformer.transform(xmlSource, result);
      fos.close();
      return;
    } catch (TransformerConfigurationException e) {
      caught = e;
    } catch (TransformerException e) {
      caught = e;
    } catch (IOException e) {
      caught = e;
    }
    throw new RuntimeException("Unable to complete the xslt tranform", caught);
  }

  private void transformExistingIntoTopicXml() {
    File[] children = fOutDir.listFiles();
    if (children != null) {
      for (int i = 0, n = children.length; i < n; ++i) {
        File file = children[i];
        freshenIf(file);
      }
    }
  }

  private File tryReplaceSuffix(File file, String oldSuffix, String newSuffix) {
    String name = file.getName();
    if (name.endsWith(oldSuffix)) {
      String baseName = name.substring(0, name.length() - oldSuffix.length());
      return new File(file.getParent(), baseName + newSuffix);
    } else {
      return null;
    }
  }

  private final File[] fClassPath;
  private final String[] fPackages;
  private final PrintStream fErr;
  private final String fFileBase;
  private final String fFileType;
  private final boolean fGenerateHtml;
  private final String[] fHtmlFileBases;
  private final File[] fImagePath;
  private final PrintStream fOut;
  private final File fOutDir;
  private final File fOverviewFile;
  private final File[] fSourcePath;
  private final String fTitle;
}
