/*
 * Copyright (C) 2010 Google Inc.
 *
 * Licensed 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 com.google.doclava;

import com.google.clearsilver.jsilver.data.Data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

public class NavTree {

  /* @deprecated This method was used for an older version of DAC, circa 2012, retired May 2018 */
  public static void writeNavTree(String dir, String refPrefix) {
    List<Node> children = new ArrayList<Node>();
    for (PackageInfo pkg : Doclava.choosePackages()) {
      children.add(makePackageNode(pkg));
    }
    Node node = new Node("Reference", dir + refPrefix + "packages.html", children, null);

    StringBuilder buf = new StringBuilder();
    if (false) {
      // if you want a root node
      buf.append("[");
      node.render(buf);
      buf.append("]");
    } else {
      // if you don't want a root node
      node.renderChildren(buf);
    }

    Data data = Doclava.makeHDF();
    data.setValue("reference_tree", buf.toString());
    if (refPrefix == "gms-"){
      ClearPage.write(data, "gms_navtree_data.cs", "gms_navtree_data.js");
    } else if (refPrefix == "gcm-"){
      ClearPage.write(data, "gcm_navtree_data.cs", "gcm_navtree_data.js");
    } else if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
        ClearPage.write(data, "navtree_data.cs", dir + Doclava.libraryRoot
          + "navtree_data.js");
    } else {
      ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
    }
  }

  /**
   * Write the YAML formatted navigation tree.
   * This is intended to replace writeYamlTree(), but for now requires an explicit opt-in via
   * the yamlV2 flag in the doclava command. This version creates a yaml file with all classes,
   * interface, exceptions, etc. separated into collapsible groups.
   */
  public static void writeYamlTree2(String dir, String fileName){
    List<Node> children = new ArrayList<Node>();
    for (PackageInfo pkg : Doclava.choosePackages()) {
      children.add(makePackageNode(pkg));
    }
    Node node = new Node("Reference", Doclava.ensureSlash(dir) + "packages.html", children, null);
    StringBuilder buf = new StringBuilder();

    node.renderChildrenYaml(buf, 0);

    Data data = Doclava.makeHDF();
    data.setValue("reference_tree", buf.toString());

    if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
      dir = Doclava.ensureSlash(dir) + Doclava.libraryRoot;
    }

    data.setValue("docs.classes.link", Doclava.ensureSlash(dir) + "classes.html");
    data.setValue("docs.packages.link", Doclava.ensureSlash(dir) + "packages.html");

    ClearPage.write(data, "yaml_navtree2.cs", Doclava.ensureSlash(dir) + fileName);

  }


  /**
   * Write the YAML formatted navigation tree (legacy version).
   * This creates a yaml file with package names followed by all
   * classes, interfaces, exceptions, etc. But they are not separated by classes, interfaces, etc.
   * It also nests any nested classes under the parent class, instead of listing them as siblings.
   * @see "http://yaml.org/"
   */
  public static void writeYamlTree(String dir, String fileName){
    Data data = Doclava.makeHDF();
    Collection<ClassInfo> classes = Converter.rootClasses();

    SortedMap<String, Object> sorted = new TreeMap<String, Object>();
    for (ClassInfo cl : classes) {
      if (cl.isHiddenOrRemoved()) {
        continue;
      }
      sorted.put(cl.qualifiedName(), cl);

      PackageInfo pkg = cl.containingPackage();
      String name;
      if (pkg == null) {
        name = "";
      } else {
        name = pkg.name();
      }
      sorted.put(name, pkg);
    }

    data = makeYamlHDF(sorted, "docs.pages", data);

    if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
      dir = Doclava.ensureSlash(dir) + Doclava.libraryRoot;
    }

    data.setValue("docs.classes.link", Doclava.ensureSlash(dir) + "classes.html");
    data.setValue("docs.packages.link", Doclava.ensureSlash(dir) + "packages.html");

    ClearPage.write(data, "yaml_navtree.cs", Doclava.ensureSlash(dir) + fileName);
  }

  public static Data makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data) {

    String key = "docs.pages.";
    int i = 0;
    for (String s : sorted.keySet()) {
      Object o = sorted.get(s);

      if (o instanceof PackageInfo) {
        PackageInfo pkg = (PackageInfo) o;

        data.setValue("docs.pages." + i + ".id", "" + i);
        data.setValue("docs.pages." + i + ".label", pkg.name());
        data.setValue("docs.pages." + i + ".shortname", "API");
        data.setValue("docs.pages." + i + ".apilevel", pkg.getSince());
        data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
        data.setValue("docs.pages." + i + ".type", "package");
      } else if (o instanceof ClassInfo) {
        ClassInfo cl = (ClassInfo) o;

        // skip classes that are the child of another class, recursion will handle those.
        if (cl.containingClass() == null) {

          data.setValue("docs.pages." + i + ".id", "" + i);
          data = makeYamlHDF(cl, "docs.pages."+i, data);
        }
      }

      i++;
    }

    return data;
  }

  public static Data makeYamlHDF(ClassInfo cl, String base, Data data) {
    data.setValue(base + ".label", cl.name());
    data.setValue(base + ".shortname", cl.name().substring(cl.name().lastIndexOf(".")+1));
    data.setValue(base + ".link", cl.htmlPage());
    data.setValue(base + ".type", cl.kind());

    if (cl.innerClasses().size() > 0) {
      int j = 0;
      for (ClassInfo cl2 : cl.innerClasses()) {
        if (cl2.isHiddenOrRemoved()) {
          continue;
        }
        data = makeYamlHDF(cl2, base + ".children." + j, data);
        j++;
      }
    }

    return data;
  }

  private static Node makePackageNode(PackageInfo pkg) {
    List<Node> children = new ArrayList<Node>();

    addClassNodes(children, "Annotations", pkg.annotations());
    addClassNodes(children, "Interfaces", pkg.interfaces());
    addClassNodes(children, "Classes", pkg.ordinaryClasses());
    addClassNodes(children, "Enums", pkg.enums());
    addClassNodes(children, "Exceptions", pkg.exceptions());
    addClassNodes(children, "Errors", pkg.errors());

    return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
  }

  private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
    List<Node> children = new ArrayList<Node>();

    for (ClassInfo cl : classes) {
      if (cl.checkLevel()) {
        children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince(), cl.getArtifact()));
      }
    }

    if (children.size() > 0) {
      parent.add(new Node(label, null, children, null));
    }
  }

  private static class Node {
    private String mLabel;
    private String mLink;
    List<Node> mChildren;
    private String mSince;
    private String mArtifact;

    Node(String label, String link, List<Node> children, String since) {
      this(label, link, children, since, null);
    }

    Node(String label, String link, List<Node> children, String since, String artifact) {
      mLabel = label;
      mLink = link;
      mChildren = children;
      mSince = since;
      mArtifact = artifact;
    }

    static void renderString(StringBuilder buf, String s) {
      if (s == null) {
        buf.append("null");
      } else {
        buf.append('"');
        final int N = s.length();
        for (int i = 0; i < N; i++) {
          char c = s.charAt(i);
          if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
            buf.append(c);
          } else {
            buf.append("\\u");
            for (int j = 0; i < 4; i++) {
              char x = (char) (c & 0x000f);
              if (x >= 10) {
                x = (char) (x - 10 + 'a');
              } else {
                x = (char) (x + '0');
              }
              buf.append(x);
              c >>= 4;
            }
          }
        }
        buf.append('"');
      }
    }

    void renderChildren(StringBuilder buf) {
      List<Node> list = mChildren;
      if (list == null || list.size() == 0) {
        // We output null for no children. That way empty lists here can just
        // be a byproduct of how we generate the lists.
        buf.append("null");
      } else {
        buf.append("[ ");
        final int N = list.size();
        for (int i = 0; i < N; i++) {
          list.get(i).render(buf);
          if (i != N - 1) {
            buf.append(", ");
          }
        }
        buf.append(" ]\n");
      }
    }

    void render(StringBuilder buf) {
      buf.append("[ ");
      renderString(buf, mLabel);
      buf.append(", ");
      renderString(buf, mLink);
      buf.append(", ");
      renderChildren(buf);
      buf.append(", ");
      renderString(buf, mSince);
      buf.append(", ");
      renderString(buf, mArtifact);
      buf.append(" ]");
    }


    // YAML VERSION


    static void renderStringYaml(StringBuilder buf, String s) {
      if (s != null) {
        final int N = s.length();
        for (int i = 0; i < N; i++) {
          char c = s.charAt(i);
          if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
            buf.append(c);
          } else {
            buf.append("\\u");
            for (int j = 0; i < 4; i++) {
              char x = (char) (c & 0x000f);
              if (x >= 10) {
                x = (char) (x - 10 + 'a');
              } else {
                x = (char) (x + '0');
              }
              buf.append(x);
              c >>= 4;
            }
          }
        }
      }
    }
    void renderChildrenYaml(StringBuilder buf, int depth) {
      List<Node> list = mChildren;
      if (list != null && list.size() > 0) {
        if (depth > 0) {
          buf.append("\n\n" + getIndent(depth));
          buf.append("section:");
        }
        final int N = list.size();
        for (int i = 0; i < N; i++) {
          // get each child Node and render it
          list.get(i).renderYaml(buf, depth);
        }
        // Extra line break after each "section"
        buf.append("\n");
      }
    }
    void renderYaml(StringBuilder buf, int depth) {
      buf.append("\n" + getIndent(depth));
      buf.append("- title: \"");
      renderStringYaml(buf, mLabel);
      buf.append("\"");
      // Add link path, if it exists (the class/interface toggles don't have links)
      if (mLink != null) {
        buf.append("\n" + getIndent(depth));
        buf.append("  path: ");
        renderStringYaml(buf, "/" + mLink);
        // add the API level info only if we have it
        if (mSince != null) {
          buf.append("\n" + getIndent(depth));
          buf.append("  version_added: ");
          renderStringYaml(buf, "'" + mSince + "'");
        }
      }
      // try rendering child Nodes
      renderChildrenYaml(buf, depth + 1);
    }
    String getIndent(int depth) {
      String spaces = "";
      for (int i = 0; i < depth; i++) {
        spaces += "  ";
      }
      return spaces;
    }
  }
}