/*
 * Copyright (C) 2013 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 java.io.*;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.File;

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

import org.ccil.cowan.tagsoup.*;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

/**
* Metadata associated with a specific documentation page. Extracts
* metadata based on the page's declared hdf vars (meta.tags and others)
* as well as implicit data relating to the page, such as url, type, etc.
* Includes a Node class that represents the metadata and lets it attach
* to parent/child elements in the tree metadata nodes for all pages.
* Node also includes methods for rendering the node tree to a json file
* in docs output, which is then used by JavaScript to load metadata
* objects into html pages.
*/

public class PageMetadata {
  File mSource;
  String mDest;
  String mTagList;
  static boolean sLowercaseTags = true;
  static boolean sLowercaseKeywords = true;
  //static String linkPrefix = (Doclava.META_DBG) ? "/" : "http://developer.android.com/";
  /**
   * regex pattern to match javadoc @link and similar tags. Extracts
   * root symbol to $1.
   */
  private static final Pattern JD_TAG_PATTERN =
      Pattern.compile("\\{@.*?[\\s\\.\\#]([A-Za-z\\(\\)\\d_]+)(?=\u007D)\u007D");

  public PageMetadata(File source, String dest, List<Node> taglist) {
    mSource = source;
    mDest = dest;

    if (dest != null) {
      int len = dest.length();
      if (len > 1 && dest.charAt(len - 1) != '/') {
        mDest = dest + '/';
      } else {
        mDest = dest;
      }
    }
  }

  /**
  * Given a list of metadata nodes organized by type, sort the
  * root nodes by type name and render the types and their child
  * metadata nodes to a json file in the out dir.
  *
  * @param rootTypeNodesList A list of root metadata nodes, each
  *        representing a type and it's member child pages.
  */
  public static void WriteList(List<Node> rootTypeNodesList) {

    Collections.sort(rootTypeNodesList, BY_TYPE_NAME);
    Node pageMeta = new Node.Builder().setLabel("TOP").setChildren(rootTypeNodesList).build();

    StringBuilder buf = new StringBuilder();
    // write the taglist to string format
    pageMeta.renderTypeResources(buf);
    pageMeta.renderTypesByTag(buf);
    // write the taglist to js file
    Data data = Doclava.makeHDF();
    data.setValue("reference_tree", buf.toString());
    ClearPage.write(data, "jd_lists_unified.cs", "jd_lists_unified.js");
  }

  /**
  * Extract supported metadata values from a page and add them as
  * a child node of a root node based on type. Some metadata values
  * are normalized. Unsupported metadata fields are ignored. See
  * Node for supported metadata fields and methods for accessing values.
  *
  * @param docfile The file from which to extract metadata.
  * @param dest The output path for the file, used to set link to page.
  * @param filename The file from which to extract metadata.
  * @param hdf Data object in which to store the metadata values.
  * @param tagList The file from which to extract metadata.
  */
  public static void setPageMetadata(String docfile, String dest, String filename,
      Data hdf, List<Node> tagList) {
    //exclude this page if author does not want it included
    boolean excludeNode = "true".equals(hdf.getValue("excludeFromSuggestions",""));

    //check whether summary and image exist and if not, get them from itemprop/markup
    Boolean needsSummary = "".equals(hdf.getValue("page.metaDescription", ""));
    Boolean needsImage = "".equals(hdf.getValue("page.image", ""));
    if ((needsSummary) || (needsImage)) {
      //try to extract the metadata from itemprop and markup
      inferMetadata(docfile, hdf, needsSummary, needsImage);
    }

    //extract available metadata and set it in a node
    if (!excludeNode) {
      Node pageMeta = new Node.Builder().build();
      pageMeta.setLabel(getTitleNormalized(hdf, "page.title"));
      pageMeta.setTitleFriendly(hdf.getValue("page.titleFriendly",""));
      pageMeta.setSummary(hdf.getValue("page.metaDescription",""));
      pageMeta.setLink(getPageUrlNormalized(filename));
      pageMeta.setGroup(getStringValueNormalized(hdf,"sample.group"));
      pageMeta.setKeywords(getPageTagsNormalized(hdf, "page.tags"));
      pageMeta.setTags(getPageTagsNormalized(hdf, "meta.tags"));
      pageMeta.setImage(getImageUrlNormalized(hdf.getValue("page.image", "")));
      pageMeta.setLang(getLangStringNormalized(filename));
      pageMeta.setType(getStringValueNormalized(hdf, "page.type"));
      appendMetaNodeByType(pageMeta, tagList);
    }
  }

  /**
  * Attempt to infer page metadata based on the contents of the
  * file. Load and parse the file as a dom tree. Select values
  * in this order: 1. dom node specifically tagged with
  * microdata (itemprop). 2. first qualitifed p or img node.
  *
  * @param docfile The file from which to extract metadata.
  * @param hdf Data object in which to store the metadata values.
  * @param needsSummary Whether to extract summary metadata.
  * @param needsImage Whether to extract image metadata.
  */
  public static void inferMetadata(String docfile, Data hdf,
      Boolean needsSummary, Boolean needsImage) {
    String sum = "";
    String imageUrl = "";
    String sumFrom = needsSummary ? "none" : "hdf";
    String imgFrom = needsImage ? "none" : "hdf";
    String filedata = hdf.getValue("commentText", "");
    if (Doclava.META_DBG) System.out.println("----- " + docfile + "\n");

    try {
      XPathFactory xpathFac = XPathFactory.newInstance();
      XPath xpath = xpathFac.newXPath();
      InputStream inputStream = new ByteArrayInputStream(filedata.getBytes());
      XMLReader reader = new Parser();
      reader.setFeature(Parser.namespacesFeature, false);
      reader.setFeature(Parser.namespacePrefixesFeature, false);
      reader.setFeature(Parser.ignoreBogonsFeature, true);

      Transformer transformer = TransformerFactory.newInstance().newTransformer();
      DOMResult result = new DOMResult();
      transformer.transform(new SAXSource(reader, new InputSource(inputStream)), result);
      org.w3c.dom.Node htmlNode = result.getNode();

      if (needsSummary) {
        StringBuilder sumStrings = new StringBuilder();
        XPathExpression ItempropDescExpr = xpath.compile("/descendant-or-self::*"
            + "[@itemprop='description'][1]//text()[string(.)]");
        org.w3c.dom.NodeList nodes = (org.w3c.dom.NodeList) ItempropDescExpr.evaluate(htmlNode,
            XPathConstants.NODESET);
        if (nodes.getLength() > 0) {
          for (int i = 0; i < nodes.getLength(); i++) {
            String tx = nodes.item(i).getNodeValue();
            sumStrings.append(tx);
            sumFrom = "itemprop";
          }
        } else {
          XPathExpression FirstParaExpr = xpath.compile("//p[not(../../../"
              + "@class='notice-developers') and not(../@class='sidebox')"
              + "and not(@class)]//text()");
          nodes = (org.w3c.dom.NodeList) FirstParaExpr.evaluate(htmlNode, XPathConstants.NODESET);
          if (nodes.getLength() > 0) {
            for (int i = 0; i < nodes.getLength(); i++) {
              String tx = nodes.item(i).getNodeValue();
              sumStrings.append(tx + " ");
              sumFrom = "markup";
            }
          }
        }
        //found a summary string, now normalize it
        sum = sumStrings.toString().trim();
        if ((sum != null) && (!"".equals(sum))) {
          sum = getSummaryNormalized(sum);
        }
        //normalized summary ended up being too short to be meaningful
        if ("".equals(sum)) {
           if (Doclava.META_DBG) System.out.println("Warning: description too short! ("
            + sum.length() + "chars) ...\n\n");
        }
        //summary looks good, store it to the file hdf data
        hdf.setValue("page.metaDescription", sum);
      }
      if (needsImage) {
        XPathExpression ItempropImageExpr = xpath.compile("//*[@itemprop='image']/@src");
        org.w3c.dom.NodeList imgNodes = (org.w3c.dom.NodeList) ItempropImageExpr.evaluate(htmlNode,
            XPathConstants.NODESET);
        if (imgNodes.getLength() > 0) {
          imageUrl = imgNodes.item(0).getNodeValue();
          imgFrom = "itemprop";
        } else {
          XPathExpression FirstImgExpr = xpath.compile("//img/@src");
          imgNodes = (org.w3c.dom.NodeList) FirstImgExpr.evaluate(htmlNode, XPathConstants.NODESET);
          if (imgNodes.getLength() > 0) {
            //iterate nodes looking for valid image url and normalize.
            for (int i = 0; i < imgNodes.getLength(); i++) {
              String tx = imgNodes.item(i).getNodeValue();
              //qualify and normalize the image
              imageUrl = getImageUrlNormalized(tx);
              //this img src did not qualify, keep looking...
              if ("".equals(imageUrl)) {
                if (Doclava.META_DBG) System.out.println("    >>>>> Discarded image: " + tx);
                continue;
              } else {
                imgFrom = "markup";
                break;
              }
            }
          }
        }
        //img src url looks good, store it to the file hdf data
        hdf.setValue("page.image", imageUrl);
      }
      if (Doclava.META_DBG) System.out.println("Image (" + imgFrom + "): " + imageUrl);
      if (Doclava.META_DBG) System.out.println("Summary (" + sumFrom + "): " + sum.length()
          + " chars\n\n" + sum + "\n");
      return;

    } catch (Exception e) {
      if (Doclava.META_DBG) System.out.println("    >>>>> Exception: " + e + "\n");
    }
  }

  /**
  * Normalize a comma-delimited, multi-string value. Split on commas, remove
  * quotes, trim whitespace, optionally make keywords/tags lowercase for
  * easier matching.
  *
  * @param hdf Data object in which the metadata values are stored.
  * @param tag The hdf var from which the metadata was extracted.
  * @return A normalized string value for the specified tag.
  */
  public static String getPageTagsNormalized(Data hdf, String tag) {

    String normTags = "";
    StringBuilder tags = new StringBuilder();
    String tagList = hdf.getValue(tag, "");
    if (tag.equals("meta.tags") && (tagList.equals(""))) {
      //use keywords as tags if no meta tags are available
      tagList = hdf.getValue("page.tags", "");
    }
    if (!tagList.equals("")) {
      tagList = tagList.replaceAll("\"", "");

      String[] tagParts = tagList.split("[,\u3001]");
      for (int iter = 0; iter < tagParts.length; iter++) {
        tags.append("\"");
        if (tag.equals("meta.tags") && sLowercaseTags) {
          tagParts[iter] = tagParts[iter].toLowerCase();
        } else if (tag.equals("page.tags") && sLowercaseKeywords) {
          tagParts[iter] = tagParts[iter].toLowerCase();
        }
        if (tag.equals("meta.tags")) {
          //tags.append("#"); //to match hashtag format used with yt/blogger resources
          tagParts[iter] = tagParts[iter].replaceAll(" ","");
        }
        tags.append(tagParts[iter].trim());
        tags.append("\"");
        if (iter < tagParts.length - 1) {
          tags.append(",");
        }
      }
    }
    //write this back to hdf to expose through js
    if (tag.equals("meta.tags")) {
      hdf.setValue(tag, tags.toString());
    }
    return tags.toString();
  }

  /**
  * Normalize a string for which only a single value is supported.
  * Extract the string up to the first comma, remove quotes, remove
  * any forward-slash prefix, trim any whitespace, optionally make
  * lowercase for easier matching.
  *
  * @param hdf Data object in which the metadata values are stored.
  * @param tag The hdf var from which the metadata should be extracted.
  * @return A normalized string value for the specified tag.
  */
  public static String getStringValueNormalized(Data hdf, String tag) {
    StringBuilder outString =  new StringBuilder();
    String tagList = hdf.getValue(tag, "");
    tagList.replaceAll("\"", "");
    if (!tagList.isEmpty()) {
      int end = tagList.indexOf(",");
      if (end != -1) {
        tagList = tagList.substring(0,end);
      }
      tagList = tagList.startsWith("/") ? tagList.substring(1) : tagList;
      if ("sample.group".equals(tag) && sLowercaseTags) {
        tagList = tagList.toLowerCase();
      }
      outString.append(tagList.trim());
    }
    return outString.toString();
  }

  /**
  * Normalize a page title. Extract the string, remove quotes, remove
  * markup, and trim any whitespace.
  *
  * @param hdf Data object in which the metadata values are stored.
  * @param tag The hdf var from which the metadata should be extracted.
  * @return A normalized string value for the specified tag.
  */
  public static String getTitleNormalized(Data hdf, String tag) {
    StringBuilder outTitle =  new StringBuilder();
    String title = hdf.getValue(tag, "");
    if (!title.isEmpty()) {
      title = escapeString(title);
      if (title.indexOf("<span") != -1) {
        String[] splitTitle = title.split("<span(.*?)</span>");
        title = splitTitle[0];
        for (int j = 1; j < splitTitle.length; j++) {
          title.concat(splitTitle[j]);
        }
      }
      outTitle.append(title.trim());
    }
    return outTitle.toString();
  }

  /**
  * Extract and normalize a page's language string based on the
  * lowercased dir path. Non-supported langs are ignored and assigned
  * the default lang string of "en".
  *
  * @param filename A path string to the file relative to root.
  * @return A normalized lang value.
  */
  public static String getLangStringNormalized(String filename) {
    String[] stripStr = filename.toLowerCase().split("\\/");
    String outFrag = "en";
    if (stripStr.length > 0) {
      for (String t : DocFile.DEVSITE_VALID_LANGS) {
        if ("intl".equals(stripStr[0])) {
          if (t.equals(stripStr[1])) {
            outFrag = stripStr[1];
            break;
          }
        }
      }
    }
    return outFrag;
  }

  /**
  * Normalize a page summary string and truncate as needed. Strings
  * exceeding max_chars are truncated at the first word boundary
  * following the max_size marker. Strings smaller than min_chars
  * are discarded (as they are assumed to be too little context).
  *
  * @param s String extracted from the page as it's summary.
  * @return A normalized string value.
  */
  public static String getSummaryNormalized(String s) {
    String str = "";
    int max_chars = 250;
    int min_chars = 50;
    int marker = 0;
    if (s.length() < min_chars) {
      return str;
    } else {
      str = s.replaceAll("^\"|\"$", "");
      str = str.replaceAll("\\s+", " ");
      str = JD_TAG_PATTERN.matcher(str).replaceAll("$1");
      str = escapeString(str);
      BreakIterator bi = BreakIterator.getWordInstance();
      bi.setText(str);
      if (str.length() > max_chars) {
        marker = bi.following(max_chars);
      } else {
        marker = bi.last();
      }
      str = str.substring(0, marker);
      str = str.concat("\u2026" );
    }
    return str;
  }

  public static String escapeString(String s) {
    s = s.replaceAll("\"", "&quot;");
    s = s.replaceAll("\'", "&#39;");
    s = s.replaceAll("<", "&lt;");
    s = s.replaceAll(">", "&gt;");
    s = s.replaceAll("/", "&#47;");
    return s;
  }

  //Disqualify img src urls that include these substrings
  public static String[] IMAGE_EXCLUDE = {"/triangle-", "favicon","android-logo",
      "icon_play.png", "robot-tiny"};

  public static boolean inList(String s, String[] list) {
    for (String t : list) {
      if (s.contains(t)) {
        return true;
      }
    }
    return false;
  }

  /**
  * Normalize an img src url by removing docRoot and leading
  * slash for local image references. These are added later
  * in js to support offline mode and keep path reference
  * format consistent with hrefs.
  *
  * @param url Abs or rel url sourced from img src.
  * @return Normalized url if qualified, else empty
  */
  public static String getImageUrlNormalized(String url) {
    String absUrl = "";
    // validate to avoid choosing using specific images
    if ((url != null) && (!url.equals("")) && (!inList(url, IMAGE_EXCLUDE))) {
      absUrl = url.replace("{@docRoot}", "");
      absUrl = absUrl.replaceFirst("^/(?!/)", "");
    }
    return absUrl;
  }

  /**
  * Normalize an href url by removing docRoot and leading
  * slash for local image references. These are added later
  * in js to support offline mode and keep path reference
  * format consistent with hrefs.
  *
  * @param url Abs or rel page url sourced from href
  * @return Normalized url, either abs or rel to root
  */
  public static String getPageUrlNormalized(String url) {
    String absUrl = "";
    if ((url !=null) && (!url.equals(""))) {
      absUrl = url.replace("{@docRoot}", "");
      absUrl = absUrl.replaceFirst("^/(?!/)", "");
    }
    return absUrl;
  }

  /**
  * Given a metadata node, add it as a child of a root node based on its
  * type. If there is no root node that matches the node's type, create one
  * and add the metadata node as a child node.
  *
  * @param gNode The node to attach to a root node or add as a new root node.
  * @param rootList The current list of root nodes.
  * @return The updated list of root nodes.
  */
  public static List<Node> appendMetaNodeByType(Node gNode, List<Node> rootList) {

    String nodeTags = gNode.getType();
    boolean matched = false;
    for (Node n : rootList) {
      if (n.getType().equals(nodeTags)) {  //find any matching type node
        n.getChildren().add(gNode);
        matched = true;
        break; // add to the first root node only
      } // tag did not match
    } // end rootnodes matching iterator
    if (!matched) {
      List<Node> mtaglist = new ArrayList<Node>(); // list of file objects that have a given type
      mtaglist.add(gNode);
      Node tnode = new Node.Builder().setChildren(mtaglist).setType(nodeTags).build();
      rootList.add(tnode);
    }
    return rootList;
  }

  /**
  * Given a metadata node, add it as a child of a root node based on its
  * tag. If there is no root node matching the tag, create one for it
  * and add the metadata node as a child node.
  *
  * @param gNode The node to attach to a root node or add as a new root node.
  * @param rootTagNodesList The current list of root nodes.
  * @return The updated list of root nodes.
  */
  public static List<Node> appendMetaNodeByTagIndex(Node gNode, List<Node> rootTagNodesList) {

    for (int iter = 0; iter < gNode.getChildren().size(); iter++) {
      if (gNode.getChildren().get(iter).getTags() != null) {
        List<String> nodeTags = gNode.getChildren().get(iter).getTags();
        boolean matched = false;
        for (String t : nodeTags) { //process each of the meta.tags
          for (Node n : rootTagNodesList) {
            if (n.getLabel().equals(t.toString())) {
              n.getTags().add(String.valueOf(iter));
              matched = true;
              break; // add to the first root node only
            } // tag did not match
          } // end rootnodes matching iterator
          if (!matched) {
            List<String> mtaglist = new ArrayList<String>(); // list of objects with a given tag
            mtaglist.add(String.valueOf(iter));
            Node tnode = new Node.Builder().setLabel(t.toString()).setTags(mtaglist).build();
            rootTagNodesList.add(tnode);
          }
        }
      }
    }
    return rootTagNodesList;
  }

  public static final Comparator<Node> BY_TAG_NAME = new Comparator<Node>() {
    public int compare (Node one, Node other) {
      return one.getLabel().compareTo(other.getLabel());
    }
  };

  public static final Comparator<Node> BY_TYPE_NAME = new Comparator<Node>() {
    public int compare (Node one, Node other) {
      return one.getType().compareTo(other.getType());
    }
  };

  /**
  * A node for storing page metadata. Use Builder.build() to instantiate.
  */
  public static class Node {

    private String mLabel; // holds page.title or similar identifier
    private String mTitleFriendly; // title for card or similar use
    private String mSummary; // Summary for card or similar use
    private String mLink; //link href for item click
    private String mGroup; // from sample.group in _index.jd
    private List<String> mKeywords; // from page.tags
    private List<String> mTags; // from meta.tags
    private String mImage; // holds an href, fully qualified or relative to root
    private List<Node> mChildren;
    private String mLang;
    private String mType; // can be file, dir, video show, announcement, etc.

    private Node(Builder builder) {
      mLabel = builder.mLabel;
      mTitleFriendly = builder.mTitleFriendly;
      mSummary = builder.mSummary;
      mLink = builder.mLink;
      mGroup = builder.mGroup;
      mKeywords = builder.mKeywords;
      mTags = builder.mTags;
      mImage = builder.mImage;
      mChildren = builder.mChildren;
      mLang = builder.mLang;
      mType = builder.mType;
    }

    private static class Builder {
      private String mLabel, mTitleFriendly, mSummary, mLink, mGroup, mImage, mLang, mType;
      private List<String> mKeywords = null;
      private List<String> mTags = null;
      private List<Node> mChildren = null;
      public Builder setLabel(String mLabel) { this.mLabel = mLabel; return this;}
      public Builder setTitleFriendly(String mTitleFriendly) {
        this.mTitleFriendly = mTitleFriendly; return this;
      }
      public Builder setSummary(String mSummary) {this.mSummary = mSummary; return this;}
      public Builder setLink(String mLink) {this.mLink = mLink; return this;}
      public Builder setGroup(String mGroup) {this.mGroup = mGroup; return this;}
      public Builder setKeywords(List<String> mKeywords) {
        this.mKeywords = mKeywords; return this;
      }
      public Builder setTags(List<String> mTags) {this.mTags = mTags; return this;}
      public Builder setImage(String mImage) {this.mImage = mImage; return this;}
      public Builder setChildren(List<Node> mChildren) {this.mChildren = mChildren; return this;}
      public Builder setLang(String mLang) {this.mLang = mLang; return this;}
      public Builder setType(String mType) {this.mType = mType; return this;}
      public Node build() {return new Node(this);}
    }

    /**
    * Render a tree of metadata nodes organized by type.
    * @param buf Output buffer to render to.
    */
    void renderTypeResources(StringBuilder buf) {
      List<Node> list = mChildren; //list of type rootnodes
      if (list == null || list.size() == 0) {
        buf.append("null");
      } else {
        final int n = list.size();
        for (int i = 0; i < n; i++) {
          buf.append("var " + list.get(i).mType.toUpperCase() + "_RESOURCES = [");
          list.get(i).renderTypes(buf); //render this type's children
          buf.append("\n];\n\n");
        }
      }
    }
    /**
    * Render all metadata nodes for a specific type.
    * @param buf Output buffer to render to.
    */
    void renderTypes(StringBuilder buf) {
      List<Node> list = mChildren;
      if (list == null || list.size() == 0) {
        buf.append("nulltype");
      } else {
        final int n = list.size();
        for (int i = 0; i < n; i++) {
          buf.append("\n      {\n");
          buf.append("        \"title\":\"" + list.get(i).mLabel + "\",\n" );
          buf.append("        \"titleFriendly\":\"" + list.get(i).mTitleFriendly + "\",\n" );
          buf.append("        \"summary\":\"" + list.get(i).mSummary + "\",\n" );
          buf.append("        \"url\":\"" + list.get(i).mLink + "\",\n" );
          buf.append("        \"group\":\"" + list.get(i).mGroup + "\",\n" );
          list.get(i).renderArrayType(buf, list.get(i).mKeywords, "keywords");
          list.get(i).renderArrayType(buf, list.get(i).mTags, "tags");
          buf.append("        \"image\":\"" + list.get(i).mImage + "\",\n" );
          buf.append("        \"lang\":\"" + list.get(i).mLang + "\",\n" );
          buf.append("        \"type\":\"" + list.get(i).mType + "\"");
          buf.append("\n      }");
          if (i != n - 1) {
            buf.append(", ");
          }
        }
      }
    }

    /**
    * Build and render a list of tags associated with each type.
    * @param buf Output buffer to render to.
    */
    void renderTypesByTag(StringBuilder buf) {
      List<Node> list = mChildren; //list of rootnodes
      if (list == null || list.size() == 0) {
        buf.append("null");
      } else {
        final int n = list.size();
        for (int i = 0; i < n; i++) {
        buf.append("var " + list.get(i).mType.toUpperCase() + "_BY_TAG = {");
        List<Node> mTagList = new ArrayList(); //list of rootnodes
        mTagList = appendMetaNodeByTagIndex(list.get(i), mTagList);
        list.get(i).renderTagIndices(buf, mTagList);
          buf.append("\n};\n\n");
        }
      }
    }

    /**
    * Render a list of tags associated with a type, including the
    * tag's indices in the type array.
    * @param buf Output buffer to render to.
    * @param tagList Node tree of types to render.
    */
    void renderTagIndices(StringBuilder buf, List<Node> tagList) {
      List<Node> list = tagList;
      if (list == null || list.size() == 0) {
        buf.append("");
      } else {
        final int n = list.size();
        for (int i = 0; i < n; i++) {
          buf.append("\n    " + list.get(i).mLabel + ":[");
          renderArrayValue(buf, list.get(i).mTags);
          buf.append("]");
          if (i != n - 1) {
            buf.append(", ");
          }
        }
      }
    }

    /**
    * Render key:arrayvalue pair.
    * @param buf Output buffer to render to.
    * @param type The list value to render as an arrayvalue.
    * @param key The key for the pair.
    */
    void renderArrayType(StringBuilder buf, List<String> type, String key) {
      buf.append("        \"" + key + "\": [");
      renderArrayValue(buf, type);
      buf.append("],\n");
    }

    /**
    * Render an array value to buf, with special handling of unicode characters.
    * @param buf Output buffer to render to.
    * @param type The list value to render as an arrayvalue.
    */
    void renderArrayValue(StringBuilder buf, List<String> type) {
      List<String> list = type;
      if (list != null) {
        final int n = list.size();
        for (int i = 0; i < n; i++) {
          String tagval = list.get(i).toString();
          final int L = tagval.length();
          for (int t = 0; t < L; t++) {
            char c = tagval.charAt(t);
            if (c >= Character.MIN_HIGH_SURROGATE && c <= Character.MAX_HIGH_SURROGATE ) {
              // we have a UTF-16 multi-byte character
              int codePoint = tagval.codePointAt(t);
              int charSize = Character.charCount(codePoint);
              t += charSize - 1;
              buf.append(String.format("\\u%04x",codePoint));
            } else if (c >= ' ' && c <= '~' && c != '\\') {
              buf.append(c);
            } else { 
              // we are encoding a two byte character
              buf.append(String.format("\\u%04x", (int) c));
            }
          }
          if (i != n - 1) {
            buf.append(",");
          }
        }
      }
    }

    public String getLabel() {
      return mLabel;
    }

    public void setLabel(String label) {
       mLabel = label;
    }

    public String getTitleFriendly() {
      return mTitleFriendly;
    }

    public void setTitleFriendly(String title) {
       mTitleFriendly = title;
    }

    public String getSummary() {
      return mSummary;
    }

    public void setSummary(String summary) {
       mSummary = summary;
    }

    public String getLink() {
      return mLink;
    }

    public void setLink(String ref) {
       mLink = ref;
    }

    public String getGroup() {
      return mGroup;
    }

    public void setGroup(String group) {
      mGroup = group;
    }

    public List<String> getTags() {
        return mTags;
    }

    public void setTags(String tags) {
      if ("".equals(tags)) {
        mTags = null;
      } else {
        List<String> tagList = new ArrayList();
        String[] tagParts = tags.split(",");

        for (String t : tagParts) {
          tagList.add(t);
        }
        mTags = tagList;
      }
    }

    public List<String> getKeywords() {
        return mKeywords;
    }

    public void setKeywords(String keywords) {
      if ("".equals(keywords)) {
        mKeywords = null;
      } else {
        List<String> keywordList = new ArrayList();
        String[] keywordParts = keywords.split(",");

        for (String k : keywordParts) {
          keywordList.add(k);
        }
        mKeywords = keywordList;
      }
    }

    public String getImage() {
        return mImage;
    }

    public void setImage(String ref) {
       mImage = ref;
    }

    public List<Node> getChildren() {
        return mChildren;
    }

    public void setChildren(List<Node> node) {
        mChildren = node;
    }

    public String getLang() {
      return mLang;
    }

    public void setLang(String lang) {
      mLang = lang;
    }

    public String getType() {
      return mType;
    }

    public void setType(String type) {
      mType = type;
    }
  }
}
