/*
 * 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.log4j.chainsaw;

import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;


/**
 *
 * A TreeModel that represents the Loggers for a given LogPanel
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 */
class LogPanelLoggerTreeModel extends DefaultTreeModel
  implements LoggerNameListener {
  private Map fullPackageMap = new HashMap();
  private final Logger logger = LogManager.getLogger(LogPanelLoggerTreeModel.class);

  LogPanelLoggerTreeModel() {
    super(new LogPanelTreeNode("Root Logger"));
  }

  /* (non-Javadoc)
   * @see org.apache.log4j.chainsaw.LoggerNameListener#loggerNameAdded(java.lang.String)
   */
  public void loggerNameAdded(final String loggerName) {
    //invoke later, not on current EDT
    SwingUtilities.invokeLater(
            () -> addLoggerNameInDispatchThread(loggerName));
  }

  public void reset() {
      DefaultMutableTreeNode current = (DefaultMutableTreeNode) getRoot();
      current.removeAllChildren();
      fullPackageMap.clear();
      nodeStructureChanged(current);
  }

  private void addLoggerNameInDispatchThread(final String loggerName) {
    String[] packages = tokenize(loggerName);

    /**
     * The packages array is effectively the tree
     * path that must exist within the tree, so
     * we walk the tree ensuring each level is present
     */
    DefaultMutableTreeNode current = (DefaultMutableTreeNode) getRoot();


/**
 * This label is used to break out when descending the
 * current tree hierachy, and it has matched a package name
 * with an already existing TreeNode.
 */
outerFor: 
    for (int i = 0; i < packages.length; i++) {
      String packageName = packages[i];
      Enumeration enumeration = current.children();

      while (enumeration.hasMoreElements()) {
        DefaultMutableTreeNode child =
          (DefaultMutableTreeNode) enumeration.nextElement();
        String childName = child.getUserObject().toString();

        if (childName.equals(packageName)) {
          /**
           * This the current known branch to descend
           */
          current = child;

          /**
           * we've found it, so break back to the outer
           * for loop to continue processing further
           * down the tree
           */
          continue outerFor;
        }
      }

      /*
       * So we haven't found this index in the current children,
       * better create the child
       */
      final LogPanelTreeNode newChild = new LogPanelTreeNode(packageName);

      StringBuilder fullPackageBuf = new StringBuilder();

      for (int j = 0; j <= i; j++) {
        fullPackageBuf.append(packages[j]);

        if (j < i) {
          fullPackageBuf.append(".");
        }
      }

      logger.debug("Adding to Map " + fullPackageBuf.toString());
      fullPackageMap.put(fullPackageBuf.toString(), newChild);

      final DefaultMutableTreeNode changedNode = current;

      changedNode.add(newChild);

      final int[] changedIndices = new int[changedNode.getChildCount()];

      for (int j = 0; j < changedIndices.length; j++) {
        changedIndices[j] = j;
      }

      nodesWereInserted(
        changedNode, new int[] { changedNode.getIndex(newChild) });
      nodesChanged(changedNode, changedIndices);
      current = newChild;
    }
  }

  LogPanelTreeNode lookupLogger(String newLogger) {
    if (fullPackageMap.containsKey(newLogger)) {
      return (LogPanelTreeNode) fullPackageMap.get(newLogger);
    }else{
        logger.debug("No logger found matching '" + newLogger + "'");
        logger.debug("Map Dump: " + fullPackageMap);
    }

    return null;
  }

  /**
     * Takes the loggerName and tokenizes it into it's
     * package name lements returning the elements
     * via the Stirng[]
     * @param loggerName
     * @return array of strings representing the package hierarchy
     */
  private String[] tokenize(String loggerName) {
    StringTokenizer tok = new StringTokenizer(loggerName, ".");

    String[] tokens = new String[tok.countTokens()];

    int index = 0;

    while (tok.hasMoreTokens()) {
      tokens[index++] = tok.nextToken();
    }

    return tokens;
  }

  private static class LogPanelTreeNode extends DefaultMutableTreeNode {
    protected static Comparator nodeComparator =
            (o1, o2) -> o1.toString().compareToIgnoreCase(o2.toString());

    private LogPanelTreeNode(String logName) {
      super(logName);
    }

    public void insert(MutableTreeNode newChild, int childIndex) {
      //      logger.debug("[" + this.getUserObject() + "] inserting child " + newChild + " @ index " + childIndex);
      //      logger.debug("Children now: " + this.children);
      super.insert(newChild, childIndex);

      //	  logger.debug("Children after insert: " + this.children);
      this.children.sort(nodeComparator);

      //	  logger.debug("Children after sort: " + this.children);
    }
  }
}
